🦋 Welcome to the former MAIN() IRC channel of the Raku Programming Language (raku.org). This channel has moved to Libera (irc.libera.chat #raku)
Set by lizmat on 23 May 2021.
00:02 reportable6 left 00:04 reportable6 joined 00:10 holly left 00:31 vrurg joined 01:21 ecocode_ left 01:35 frost joined 01:48 kevin1 left 01:58 dogbert11 joined 01:59 kevin1 joined 02:00 kevin1 is now known as kjp 02:08 dogbert11 left, dogbert11 joined 03:08 linkable6 left, evalable6 left, releasable6 joined 04:08 tellable6 left, committable6 left, greppable6 left, reportable6 left, shareable6 left, nativecallable6 left, coverable6 left, benchable6 left, releasable6 left, squashable6 left, quotable6 left, notable6 left, sourceable6 left, statisfiable6 left, bloatable6 left, bisectable6 left, nativecallable6 joined, evalable6 joined 04:09 shareable6 joined, committable6 joined, coverable6 joined, benchable6 joined 04:10 statisfiable6 joined, releasable6 joined, squashable6 joined, tellable6 joined, reportable6 joined 04:11 quotable6 joined, notable6 joined 04:16 guifa joined
guifa Is there any way during composition to reference the package that the object is being composed in? 04:16
I can *almost* do it by using method compose(\foo) { say foo.^name }, but that gives me a string reference, but I can't resolve that name into a reference 04:18
04:22 unicodable6 joined 04:23 Jimav joined
Jimav Hi, Does Raku have "version objects" like were description in P6 snopsis (forgot which)? I see "class version" but the class description does not say anything about how alpha and numeric components are handled. 04:24
The old P6 versions, I think, treated alphabetic terms as higher than any numeric term 04:25
Just looking for documentation.
guifa That's correct: alphabetic terms are higher. I don't think it's documented since (I reckon) it's assumed folks won't mix them too often 04:28
err 04:31
Backwards, alphabetics are lower, explicitly, per Rakudo src
github.com/rakudo/rakudo/blob/4183...n.pm6#L249 04:32
Jimav There used to be a fairly thorough description of "version literals" but I could not find it now searching the doc
The "mixing" is when e.g. v1.2alpha and v1.2 are compared. In P6 (at least, probably still true in Raku) this was split into 1/2/0 and 1/2/alpha (the '0' being the default for missing terms) and the 'alpha' sorted first, so 1.2alpha would be before the "final release" 1.2 04:34
If alphabetics sort lower than numbers, then 1.2alpha would be treated as more-recent than 1.2 04:36
wrong, I got that backwards 04:40
guifa The splitting (between the digits and alphas) is still true. 04:41
Basically, the regex /:r '*' || \d+ || <.alpha>+/ is used
Jimav "alpha" < 0 is correct, and what the nqp code guifa linked to does (so the alpha release comes first)
Ok, thanks. What I really was looking for was documentation I could link to which describes versions, because I maintain a Perl 5 module which purports to do P6 version sorting. 04:43
guifa Ah. I can't think of any document that goes beyond either the description in docs.raku.org for Versions, the source code, and the roast at github.com/Raku/roast/blob/dffc2a4.../version.t 04:46
We should probably boost the documentation on that to make things a bit clearer 04:47
guifa also realized that the roast doesn't have any non-numerics in there, that should probably get fixed too 04:49
Jimav Well, thanks for the clarifications. Best wishes. 04:50
guifa I believe the idea to auto break between digits and alpha was to allow,e.g., use v6c and use v6d 04:51
There are a few more tests here: github.com/Raku/roast/blob/dffc2a4.../version.t (specifically revolving around the examples in synopsis 2, which as you note, states alphabetics before numerics). Hope that those can be of help 04:54
Jimav I found the old P6 Synopsis 2 here: design.raku.org/S02.html#Version_literals
"each sorting position sorts numerically between numbers, alphabetically between alphas, and alphabetics in a position before numerics. " so it looks like it was implemented the other way 04:55
umph, scratch that comment
I'm going to link to that. 04:59
04:59 Jimav left
guifa TIL the original point of :sym<…> 05:00
design.raku.org/S02.html#Grammatical_Categories ! 05:01
I always wondered why :sym<…> was so important that it ended up getting reserved
05:07 tellable6 left, reportable6 left, nativecallable6 left, squashable6 left, releasable6 left, statisfiable6 left, coverable6 left, committable6 left, shareable6 left, evalable6 left 05:09 Doc_Holliwood left 06:01 xinming joined 06:04 reportable6 joined, Doc_Holliwood joined 06:09 nativecallable6 joined, linkable6 joined 06:10 greppable6 joined, statisfiable6 joined 06:12 xinming left 06:13 xinming joined 06:24 frost left 06:26 stoned75 left 06:32 abraxxa joined 06:36 frost joined 06:37 abraxxa left, abraxxa joined
tyil does anyone know who set up the #raku:matrix.org room? 06:54
06:58 dolmen joined 07:04 bloatable6 joined 07:10 committable6 joined 07:11 evalable6 joined, coverable6 joined 07:12 tellable6 joined 07:26 Doc_Holliwood left 07:38 p6steve joined 07:40 Altai-man_ joined 07:53 frost left
CIAvash That room doesn't seem to exist? 07:58
08:11 shareable6 joined 08:12 releasable6 joined, Sgeo left 08:14 bisectable6 joined 08:22 morayj joined 08:32 dolmen left 08:34 ufobat joined, dolmen joined 08:36 frost joined, frost left, frost joined 08:39 frost left, frost joined, frost left 08:40 frost joined
ecocode lizmat: I once was an Apple addict too ;) 09:01
09:04 morayj left
El_Che hi ecocode 09:13
ecocode El_Che: hello 09:14
09:16 sono left 09:17 Altai-man_ left
tyil CIAvash: it still exists according to my client, but I can't join it becuase it's invite only, which is possible fallout from the freenode staff tryign to screw everyone over 09:19
CIAvash uploaded an image: (33KiB) < libera.ems.host/_matrix/media/r0/d..._13-54.png > 09:25
tyil huh
oh youre right, CIAvash, it's #freenode_#raku:matrix.org for me 09:26
I'm being dumb :<
CIAvash yeah, new room is `#raku:libera.chat` 09:28
09:34 dolmen left 09:37 dolmen joined
CIAvash Also for matrix users who are not aware, new appservice and NickServ rooms for libera.chat are @appservice:libera.chat and @NickServ:libera.chat 09:39
09:40 tyil[m] joined 09:52 stoned75 joined 09:53 dolmen left 10:02 stoned75 left 10:03 dolmen joined
CIAvash I created a Space(new & beta Matrix feature which will replace the Community feature), you should be able to join here: matrix.to/#/!afXnlmOXFxaJtpbVIR:ma...matrix.org 10:03
10:04 ComplYue[m] joined
p6steve ecocode: feels good to de-Intel 10:17
frost m: given 3|4 { when 3 {say "yes"} } 10:24
camelia ( no output )
frost m: given 3 { when 3|4 {say "yes"} }
camelia yes
frost m: say 1 ~~ 1|2, ' ', 1|2, ~~ 1 10:25
camelia 5===SORRY!5=== Error while compiling <tmp>
Expected a term, but found either infix ~~ or redundant prefix ~
(to suppress this message, please use a space like ~ ~)
at <tmp>:1
------> 3say 1 ~~ 1|2, ' ', 1|2, ~~7⏏5 1
frost m: say 1 ~~ 1|2, ' ', 1|2 ~~ 1
camelia True True
10:31 ufobat left 10:36 squashable6 joined 10:45 dolmen left 10:49 linkable6 left 11:05 dakkar joined 11:08 p6steve left 11:13 sourceable6 joined 11:22 p6steve joined 11:29 Doc_Holliwood joined 11:32 morayj joined 11:34 morayj left 11:47 dolmen joined
Doc_Holliwood how do i elegantly remove only the first thing matching a condition from a list of things? 11:52
without using a variable if possible
grep with side effect is just ugly
12:03 reportable6 left
dakkar Doc_Holliwood: lists are immutable… do you mean array? 12:11
m: my @a=(1..10);.splice(.first(*>4),1) with @a;say @a 12:13
camelia [1 2 3 4 5 7 8 9 10]
dakkar m: my @a=('a'..'z');.splice(.first(* gt 'f',:k),1) with @a;say @a 12:14
camelia [a b c d e f h i j k l m n o p q r s t u v w x y z]
dakkar Doc_Holliwood: something like that?
12:15 ufobat joined
dakkar `.splice` does the removal, `.first(&matcher, :k)` returs the first *index* (instead of the first element) 12:16
Doc_Holliwood more like <a b c a d b a x x> to <a c a d b a x x> 12:17
(only the first "b" to be removed
lizmat Doc_Holliwood: fwiw, I have recently been thinking of adding a :not named arg to .grep 12:21
ah, but that wouldn't help because you only want to remove the first
Doc_Holliwood lizmat: A callable for skip? 12:25
lizmat ah, hmmm... 12:26
Doc_Holliwood like <a b c a d b a x x>.skip(* eq 'b', 1)
dakkar m: my @a=<a b c a d b a x x>;.splice(.first(* eq 'b',:k),1) with @a;say @a 12:27
camelia [a c a d b a x x]
dakkar if you want it in place, of course
lizmat m: dd <a b c d e f>.skip(*-4) # skip(Callable) is already used 12:30
camelia ("c", "d", "e", "f").Seq
12:31 dogbert11 left 12:32 dogbert11 joined
Doc_Holliwood <a b c a d b a b x b x>.skip( where => * eq 'b', at => 2..* ) # <a b c a d b a x x> 12:32
named args =) 12:33
12:34 dogbert11 left, dogbert11 joined
Doc_Holliwood m: dd <a b c a d b a b x b x> (-) <a a> 12:37
camelia Set.new("b","d","c","x")
Doc_Holliwood darn 12:38
lizmat m: dd <a b c a d b a b x b x>.grep: { $_ ne "b" || $++ } 12:41
camelia ("a", "c", "a", "d", "b", "a", "b", "x", "b", "x").Seq
lizmat Doc_Holliwood ^^
Doc_Holliwood cheating 12:42
jast it's only cheating if someone else does it! 12:45
lizmat <a b c a d b a b x b x>.skip( where => * eq 'b', :1st )
Doc_Holliwood m: my @N = 4, 4, 1, 7, 6; my @n = sort @N; say join '', reverse flat @n.splice( @n.first({ $_ == (state $ = @N.grep(* %% 2).min) }, :k ), 1 ), @n 12:47
camelia 76414
Doc_Holliwood m: my @N = 2,7,1,5,6; @N .= sort; say join '', reverse flat @N.splice( @N.first({ $_ == (state $ = @N.grep(* %% 2).min) }, :k ), 1 ), @N 12:54
camelia 76512
13:22 dolmen left 13:26 dolmen joined 13:55 morayj joined 13:59 morayj left 14:08 linkable6 joined 14:19 Doc_Holliwould joined, Doc_Holliwood left 14:26 kevin1 joined 14:27 kjp left 14:29 tyil[m] left 14:31 vodkra left, juanfra left, xinming left 14:32 vodkra joined, xinming joined, ufobat left 14:36 Doc_Holliwould left
lizmat and another Rakudo Weekly News hits the Net: rakudoweekly.blog/2021/05/31/2021-...r-the-bus/ 14:38
raydiak lizmat++ 14:39
14:41 frost left, abraxxa left, guifa left 14:43 Doc_Holliwood joined 14:46 tyil[m] joined 14:49 abraxxa joined, guifa joined 14:52 Shaeto joined
Shaeto can't find official confirmation of @$x in the raku docs :) 15:03
m: my $x = (1,2,3); say "$_" for @$x; 15:04
camelia 1
15:06 juanfra joined 15:10 quipa joined 15:16 Shaeto left 15:23 Shaeto joined
quipa Hello! I'm thinking of developing a gui desktop app using Raku using JVM as target and gui api/library, does anyone know of a tutorial or project using such an approach? 15:35
15:35 dolmen left
moon-child quipa: I do not 15:36
it would probably function as a good stresstest of the jvm target
I think most people doing gui in raku have used the gtk bindings
quipa Yes I've seen the gtk::simple tutorials :), was just wondering if this is a possibility
since for my use case deploying something in a jar would be simpler 15:37
moon-child can't think of any reason why it wouldn't be possible
quipa Any bindings I could use to access say swing? 15:38
or any Java api for the matter
I haven't got a clue how rakudo works with JVM, but after trying to develop with a couple other JVM languages, I really wish I could do it in Raku 15:40
but JVM really is a convenient platform 15:41
15:50 dolmen joined, Shaeto left 15:51 Shaeto joined
guifa oh yay, people around now. anyone know a way to grab the parent package during composition (e.g. a reference to the outer class during an inner class' composition) 15:52
15:52 dakkar left
moon-child guifa: no idea sorry 15:53
quipa: no bindings afaik. 0x0.st/-23L.txt this seems to work, should be enough to get you started 15:54
quipa ah cool
so you can just access the apis directly? 15:55
moon-child yes
jvm has introspection so you don't have to enumerate methods and parameters by hand like you do with c 15:56
guifa oh sweet, Raku.land indexed my modules (top result when I googled it because it's faster normally than clicking through github ha) 15:58
quipa @moo
moon-child thanks, this is what I needed :)
15:59 Kaiepi left 16:00 Doc_Holliwood left, Kaiepi joined
raydiak Shaeto: docs.raku.org/type/Any#index-entry...extualizer 16:07
Shaeto raydiak: Brevity is the soul of wit :) it is very hard to find, thank you 16:10
16:11 holly joined
raydiak you're welcome :) 16:11
holly here's the start of the prolog (without tree building yet) I mentioned yesterday : github.com/zarathemage/zehpyr-prolog
I am going to work some more on it tonight 16:12
hi BTW
does not compile yet 16:13
machine learning for compilers/interpreters 16:14
16:20 jess left
guifa Altai-man: seems there's a bit more to fixing Fluent. I've been in the midst of a fairly extensive rewrite, but seeing if I can get a hotfix working in the meantime 16:20
16:20 jess joined
guifa is working to separate the srings processing from the localization manager so the latter can work with other formats 16:20
Altai-man guifa, hi! No need to really hurry, it's just something I noticed during latest Blin run. Thanks for putting your time and efforts into those modules. 16:21
vrurg++ # for doing the Blin runs when I was unable to for some time 16:22
guifa I kind of figured it might be something like that. Nonetheless, I don't want someone to try to install and get errors. Looking back though, it's kind of amazing just how many changes I've made in the intl namespace. It's like looking at ancient relics or something right now ha 16:23
Altai-man Indeed, that's a lo-ot of work, so you can be proud of yourself. :) 16:24
guifa Oof, and in doing so I found another error in Intl::CLDR 16:27
my META6 generator was including .DS_Store in the required files so errored on install
raydiak m: class A { class B { say OUTER::<::?PACKAGE> } } # guifa 16:32
camelia (A)
guifa raydiak: unfortunately, I'm working inside of the metaobject, so OUTER doesn't work. But maybe CALLER will 16:33
raydiak ah. can't help you with the MOP, don't know much about it 16:34
guifa Oof, it was a good idea, but CALLER::<::?PACKAGE> returns Nil
raydiak do you get anything in CALLER:: ? is this something you can reduce to a one-liner or gist? I'd toy with it as a puzzle if I understood more of what you were doing :) 16:36
guifa CALLER::.keys doesn't get me anything. Unfortunately golfing this results in three separate files =\ 16:37
but basically, I'm trying to find a way to have an inner class report its existance to its outer class
or rather, to the HOW, at least 16:38
16:38 sena_kun left
guifa See, after the fact, it's easy to do compose(\type) { type.WHO.keys } to get a list of all of the symbols, and loop on those values to detect child classes of a certain type 16:39
Unfortunately, those are unordered (because hashy) and I'm trying to preserve the order (to make a declarative GUI syntax, basically) 16:40
raydiak if you share the three files somewhere I'll play with it for fun and education, but I honestly don't know enough about the meta stuff to help without an example. also I have to go soon, so I might not answer until this afternoon (it's quarter to 10 AM here) 16:44
though hopefully you'll figure it out or someone else more knowledgable will chime in before that 16:45
if there's anyone in #raku-dev who isn't here, that might also be a good place to ask
16:48 zacts joined 16:54 quipa left
guifa raydiak: I'll try to golf it but probably can't do it until later this week. Altai-man just gave me a bunch of extra work to do today ;-) 16:55
and now my CPU is tied up for the next few hours: imgur.com/a/nhEChou
raydiak oh fun...reminds me of the old days of watching defrag run 16:57
guifa only about 750 more files to go ha 16:59
17:07 zacts left
raydiak oh right, it's memorial day...guess I don't have anyting to do after all 17:10
17:11 patrickb joined 17:26 stoned75 joined 17:33 dolmen left
holly oh boy, parsing rule substrings :-/ 17:38
"( of ( and a b ) c)" 17:39
s/of/or 17:53
18:04 reportable6 joined
Shaeto m: class a { method x() { say 'yes I can y' if self.can('y') }; method y() { 1 } }; a.new.x; say 'confirm it' if a.^can('yes he can y'); 18:06
camelia yes I can y
Shaeto is self.can just imported metaobject ^can ?
18:14 Shaeto_ joined 18:16 Sgeo joined 18:17 Shaeto left
guifa yeah, it appears to be so, although it's un(der)documented 18:18
Shaeto_ okay, now main question :) 18:20
m: class a { method x() { say "1" if self.can('y'); say "2" if self.can('!y'); }; method !y() { } }; a.new.x; 18:21
camelia ( no output )
18:21 Doc_Holliwood joined
Shaeto_ not sure how to "can" for private method 18:22
moritz why would you need to do that? 18:23
presence of private methods is statically known
Shaeto_ for example i am implementing g-code execution machine and i have tens of private method like !G00() ... !G99() 18:24
and i want to check on fly if my current implementation CAN execute this code
moritz m: class A { method !x() { }; say A.^private_method_table().keys 18:25
camelia 5===SORRY!5=== Error while compiling <tmp>
Missing block
at <tmp>:1
------> 3 { }; say A.^private_method_table().keys7⏏5<EOL>
expecting any of:
statement end
statement modifier
moritz m: class A { method !x() { }}; say A.^private_method_table().keys 18:26
camelia (x)
moritz Shaeto_: you could use that
Shaeto_ not so elegant as *can* but .. okay
moritz not as often used either :D 18:27
Shaeto_ in c++ i just add config hash but i am in p6 :) 18:28
moritz you know, raku also has hashes :D
guifa I suppose there's a way you could wrap the ClassHOW can to include the private_method_table, but that has potential side effects 18:30
18:31 abraxxa-home joined
moritz it should be pretty cheap to option private_method_table once and then cache it; it would just miss run-time additions to it (but that tends to be OK, because private methods are already dispatched at compile time; if you want them to be dispateched at runtime, private methods are the wrong tool) 18:33
Shaeto_ just found it is not possible to call private methods by Str name 19:11
holly is going to play space quest 1 19:16
19:30 donaldh joined
Shaeto_ so, private structures are not accessible for meta programming :( 19:30
guifa m: class A { method !foo { say "bar" } }; my $a = A.new; $a.^find_private_method('foo').($a); 19:34
camelia bar
guifa sub call-private-method ($object, $name) { $object.^find_private_method($name).($object) }; class A { method !foo { say "bar" } }; A.new.&call-private-method('foo') 19:38
evalable6 bar
guifa Shaeto_: ^^ see above
Shaeto_ guifa: interesting thank you, i have digged into Grammap.nqp/Actions.nqp and have found more interesting thing :) 19:40
m: class a { method x() { my $n = 'y'; self!"$n"(); }; method !y() { say "god" } }; a.new.x;
camelia god
guifa yeah, that's the standard way to call methods by name (be they private or public) without needing to muck around in the HOW 19:41
I was thinking you were wanting to call from outside of the object
Shaeto_ no, from inside
guifa ah, well, that's much easier :-) 19:48
Shaeto_ self!"$str"() is for private methods only
guifa ."$str"() is for public
it's really ""() is a special way of calling methods based on string, and the . and ! indicate public/private accordingly 19:49
Shaeto_ yes i see grammar rules now
guifa FWIW because it's just a string, all rules for string apply, so you can do, for instance
self!"{$str x 3}"() 19:50
(I'm not really sure *why* you'd want to, of course, but it's cool that it's not just a ." and "() circumfix, it really switches into the Q language 19:51
19:53 dolmen joined
Shaeto_ well...i just trying to understand can i love p6 or not using the test project :) 19:53
20:01 abraxxa left 20:06 donaldh left 20:22 abraxxa-home left 20:40 dolmen left
guifa 420 minutes later (there's a joke there somewhere), CLDR is now recompiled. New release will go out in a bit and then I can fix Fluent hopefully 20:42
lizmat guifa: the long re-compilation of many dependent modules is now also on my radar 20:44
nowhere near as extreme as you're seeing it, but starting to annoy me :-)
guifa lizmat: to be fair, this is not the same compilation as you're thinking of 20:45
lizmat ah?
guifa s/compilation/parsing of xml files, manipulation thereof in Raku native data structures, and creation of binary files that can be speedily loaded/ ;-) 20:46
lizmat ah, ok *phew* 20:47
guifa Based on my profiling, the bottle neck here is the module XML and its extensive use of mixins to keep everything technically a string (every XML object is really just a string that's had an XML role added to it, so getting child elements means rescanning the string to find that, the substring it, and then reapply the role, etc) 20:48
Since the process is all done once on my computer, admittedly, I've not tried too hard to be super efficient. Focus has been on end user speed and when I get my hands on RakuAST .... 20:52
guifa doees evil villian hand wringing
gfldex is there an equivalent for ^find_method for our-scoped subs? 20:57
lizmat OUR::<&foo> ? 20:58
gfldex Well, what I actually want to know is how to provide a FALLBACK for a package (so to speak).
guifa .^add_fallback ? 20:59
20:59 Shaeto_ left
gfldex That works on methods, I need the same for our scoped subs. 21:00
21:00 sono joined
gfldex Basically, I want to take control of the stash at runtime. 21:00
lizmat aaah... hmmm 21:01
21:12 b2gills joined, patrickb left
Xliff lizmat: Oh, please tell me module recompiling speed is still on your radar. 21:29
One of my biggest issues with Raku is module compile and recompile times.
holly hi Xliff 21:30
Xliff Heya, gnolly.
gfldex Xliff: one of the goal of RakuAST is to make Rakudo itself faster.
m: package p {}; dd p::.keys; 21:31
camelia ().Seq
holly Xliff, it's not gfx but look at github.com/zarathemage/zephyr-*
gfldex where does the .keys in this example actually comes from?
Xliff gfldex: Yes, I am aware. I just would like to know how fast. I just compiled that branch and will play with it later.
gfldex: I have So. Much. Code that I would like to optimize.
As of this writing, over 560,000 lines of it. 21:32
gnolly: Nice. Don't have much time for a deep dive, however. See above. 21:33
holly np
Xliff Is there a discord server for #raku? 22:04
gfldex yes
discord.gg/VzYpdQ6 22:05
Xliff Thanks, gfldex++
raydiak gfldex: Stash.keys is inherited from Map unless I've misunderstood the question again :) 22:12
22:12 evalable6 left, linkable6 left
gfldex m: package p {}; dd p::.hash; 22:13
camelia Stash element = {}
gfldex m: package p {}; dd p::.hash.HOW;
camelia (Perl6::Metamodel::ClassHOW+{<anon>} without .raku or .perl method)
gfldex m: package p {}; dd p::.HOW; 22:14
camelia (Perl6::Metamodel::ClassHOW+{<anon>} without .raku or .perl method)
gfldex Looks like a nqp::hash under the hood to me.
22:15 lgtaube joined
raydiak it may be. I just know it's being inherited from Map 22:19
m: say Stash.^find_method('keys') === Map.^find_method('keys')
camelia True
raydiak yes, it is ultimately an nqp::hash. github.com/rakudo/rakudo/blob/mast...p.pm6#L221 <== github.com/rakudo/rakudo/blob/mast...2486-L2499 <== github.com/rakudo/rakudo/blob/mast...m6#L65-L69 <== github.com/rakudo/rakudo/blob/mast....nqp#L3484 22:34
Xliff Hrm. I'm getting a "Messages Failed to Load" from discord 22:35
Can someone send another re-invite link to Discord Raku? 22:39
22:42 Doc_Holliwood left 22:51 zostay joined, kawaii_ joined, peteretep joined 23:19 evalable6 joined
holly I can write smalltalk code for my interpreter now, project is at github.com/zarathemage/zephyr-smalltalk 23:43
I still need to compile bu the core pragmas are in, declared 23:44
now I can write the full smalltalk system, which is much higher level than C
I have it stripped for writing games now 23:45
e.g. space quest 2 :-) 23:46
moon-child why do you have two 'README' files?
holly for web and editor display separately 23:47
23:48 guifa left