Add help text for "steal lock" button

Describe your use-case which is not covered by existing documentation.
Consider adding documentation or help text for the "steal lock" button. As a user of this plugin, it's unclear to me what that will actually do. What will happen to a build that's currently executing if I steal its lock? Will the job/stage/step be terminated? I don't see anything about stealing mentioned in the readme or on the plugin's info page.
Reference any relevant documentation, other materials or issues/pull requests that can be used for inspiration.
No response

Gret I issue, I tries to use DataTable in the plugin (enable filtering and other great features) and I found, that there are many actions which you newer see (because of logic issue in jelly code). Here is full list.
Unlock
Steal lock
Reserve
Unreserve
Reassign
Reset
I try to update the documentation in my branch, when I am finish

The action buttons contains tooltip text, which explains what the action does.
Therefore partly implemented by #365 .
Documentation shall be updated.


Problem Merging SVs of 10X with delly, lumpy and breakdancer.

HI Fritz,
I try to merge vcfs from 10X, delly, lumpy and breakdancer but  seems its not working as expected.
SURVIVOR Version: 1.0.7
Breakdancer:
chr19	19049089	.	.	.	.	PASS	PROGRAM=breakdancer;SVTYPE=DUP;SVLEN=304826;END=19353915	GT:DP	1/.:0
Delly:
chr19	19010583	DUP00041058	T	<DUP>	.	PASS	IMPRECISE;SVTYPE=DUP;SVMETHOD=EMBL.DELLYv0.7.8;CHR2=chr19;END=19336493;PE=35;MAPQ=60;CT=5to3;CIPOS=-1402,1402;CIEND=-1402,1402	GT:GL:GQ:FT:RCL:RC:RCR:CN:DR:DV:RR:RV	0/1:-258.088,0,-318.193:10000:PASS:2223:6586:2171:3:59:50:0:0
Lumpy:
chr19	19010582	134213	N	<DUP>	.	.	SVTYPE=DUP;STRANDS=-+:34;SVLEN=325909;END=19336491;CIPOS=0,0;CIEND=0,0;CIPOS95=-321,2;CIEND95=-2,658;IMPRECISE;SU=34;PE=34;SR=0	GT:SU:PE:SR	./.:34:34:0
TenX:
chr19	19010558	call_285_1	G	]chr19:19336749]G	23	PASS	CIPOS=-7,7;SVTYPE=BND;SVTYPE2=DUP;PS=19014659;MATEID=call_285_2;EVENT=call_285;HAP_ALLELIC_FRAC=1.0;ALLELIC_FRAC=0.022977022977;PAIRS=15;SPLIT=1;WildCov=.;MolTtl=.;MolTtlNoR=.;MolDel=.;MolDelNoR=.;MolWild=.;MolWildNoR=.;PVAL=.;BGSize=.;BGImparityPval=.;BGTtlRCnt=.;BGHP1RCnt=.;BGHP2RCnt=.;BGBaseCov=.;BGPhaseFrac=.;NRead=.;SOURCE=CNV,SV	GT	1|1

Commands:
SURVIVOR merge Sample 1000 2 1 0 0 50 BDL_MP10X_2.vcf

Expected output should have all of them but SURVIVOR took only entry of delly and lumpy.

chr19	19010582	134213	N	<DUP>	.	PASS	SUPP=2;SUPP_VEC=0011;SVLEN=325910;SVTYPE=DUP;SVMETHOD=SURVIVOR1.0.6;CHR2=chr19;END=19336491;CIPOS=0,1;CIEND=0,2;STRANDS=-+	GT:PSV:LN:DR:ST:QV:TY:ID:RAL:AAL:CO	./.:NaN:0:0,0:--:NaN:NaN:NaN:NAN:NAN:NAN	./.:NaN:0:0,0:--:NaN:NaN:NaN:NAN:NAN:NAN	0/1:NA:325910:109,0:-+:.:DUP:DUP00041058:NA:NA:chr19_19010583-chr19_19336493	./.:NA:325909:0,34:-+:.:DUP:134213:NA:NA:chr19_19010582-chr19_19336491

Reason could be: I suspect that SURVIVOR reads the input CHR, START, END, SVTYPE AND SVLEN and in case of 10X vcf, it has only chr and end which could be a reason SURVIVOR decided to skip, is it ?? Even though Size of SVs are around the 1K base in each tool.

but some 10X vcf has those entry and it has been merged:

chr2	174961946	INV00006063	C	<INV>	18	PASS	SUPP=3;SUPP_VEC=1011;SVLEN=2352715;SVTYPE=INV;SVMETHOD=SURVIVOR1.0.6;CHR2=chr2;END=177314937;CIPOS=-64,0;CIEND=-875,0;STRANDS=--	GT:PSV:LN:DR:ST:QV:TY:ID:RAL:AAL:CO	0|1:NA:2352180:0,0:++:18:INV:call_314_1:NA:NA:chr2_174961882-chr2_177314062	./.:NaN:0:0,0:--:NaN:NaN:NaN:NAN:NAN:NAN	0/1:NA:2352991:91,0:--:.:INV:INV00006063:NA:NA:chr2_174961946-chr2_177314937	./.:NA:2352973:0,5:--:.:INV:19715_1:NA:NA:chr2_174961916-chr2_177314889

But i wonder why breakdancer is not integrated ?
I also tried with only MP data (breakdancer, delly and lumpy) but still breakdancer entry is lacking in the integrated calls by SURVIVOR.
SURVIVOR merge MPSample 1000 2 1 0 0 50 BDL_MP2.vcf

chr19	19010582	134213	N	<DUP>	.	PASS	SUPP=2;SUPP_VEC=011;SVLEN=325910;SVTYPE=DUP;SVMETHOD=SURVIVOR1.0.7;CHR2=chr19;END=19336491;CIPOS=0,1;CIEND=0,2;STRANDS=-+	GT:PSV:LN:DR:ST:QV:TY:ID:RAL:AAL:CO	./.:NaN:0:0,0:--:NaN:NaN:NaN:NAN:NAN:NAN	0/1:NA:325910:109,0:-+:.:DUP:DUP00041058:NA:NA:chr19_19010583-chr19_19336493	./.:NA:325909:0,34:-+:.:DUP:134213:NA:NA:chr19_19010582-chr19_19336491

SURVIVOR merge MPSample 1000 3 1 0 0 50 BDL_MP3.vcf

got ZERO entry.

Please advice, waiting for your kind reply
PS: By the way this DUP entry is control event that has been predicted by all tools and we wanted to see them into our merge call but it seems  SURVIVOR is not taking into account.
Regards
Rupesh

Hi Rupesh,
thanks for reaching out. I think there are multiple points.

The reason is that the 10x call do not correspond in type:
]chr19:19336749]G
nor for the end coordinate: 19014659 (vs. Delly + Lumpy agreeing on the end position ~ 19336491)

Furthermore, check if the input file MPSample has no empty lines and includes the Breakdance file. Looks like its not recognized from the output you showed.

I hope that helps. Keep me posted.
Thanks
Fritz

Thanks Fritz for your quick reply.
Point 1: Any recommendations ? should i have to reformat the original vcf of 10X ? or something better option I could try ? As i mentioned 10X has some entry such that SURVIVOR takes but not all of them.
Point 2. I guess, SURVIVOR recognized it, if you see genotype entries in integrated call.
From above entry of integrated call of MPsample.

## brekadancer
/.:NaN:0:0,0:--:NaN:NaN:NaN:NAN:NAN:NAN	0/1:NA:325910:109,0:-

## Delly
+:.:DUP:DUP00041058:NA:NA:chr19_19010583-chr19_19336493

## lumpy
./.:NA:325909:0,34:-+:.:DUP:134213:NA:NA:chr19_19010582-chr19_19336491

NOTE: by the way, I checked there is not empty lines. But reason i suspect may be order of entries are changed within breakdancer compare of delly and lumpy ?? This is just my assumption, if your code taking entry based on columns setting from vcf.

Hi,
ok sorry I thought your SUPP_VEC was only 3 diggits so that is fine.
The problem is that SURVIVOR merge looks at the start and stop coordinates. Here these do not correspond with each other given the thresholds you specified.
SURVIVOR merge MPSample 1000 2 1 ..
You are asking here to allow a maximum of 1000 bp to be different between the start or the stop coordinate and you are asking to be type specific. Both are violated since 10x genomics specifies
SVTYPE=BND
And breakdance has a different start: 19049089 vs 19010583.
Also 10x has a different stop: 19014659 vs 19336491
So you could try to extend this 1000 threshold and dont require Type specific merges and see if that helps. I am just worried that you will lump together a lot of variants.
SURVIVOR merge MPSample 40000 2 0 .. .
I frankly would not do that...
I would ask if breakdancer is actually calling the right DUP??
Same for 10x genomics: 322kbp apart!
Do you know the location of the DUP since it is a control?
This probably does not help much on what you want to acchieve, but I hope you get a better insight why you are not getting the results you expect.
Cheers
Fritz

Hi ,

SURVIVOR merge MPSample 1000 2 1 ..
You are asking here to allow a maximum of 1000 bp to be different between the start or the stop coordinate and you are asking to be type specific. Both are violated since 10x genomics specifies
SVTYPE=BND
Comment: Can be true but here 10X has another "SVTYPE2=DUP" which is, I suppose no means for SURVIVOR.
##INFO=<ID=SVTYPE,Number=1,Type=String,Description="Type of structural variant">
##INFO=<ID=SVTYPE2,Number=1,Type=String,Description="Type of structural variant implied by breakends">

And breakdance has a different start: 19049089 vs 19010583. ==> AGREE
Also 10x has a different stop: 19014659 vs 19336491  == PS is actually not a END in 10X, END co-ordinate is "19336749" which is very close to lumpy and delly. But again i guess lacking of "END" tag cause the problem for SURVIVOR.
##INFO=<ID=PS,Number=1,Type=Integer,Description="Phase set assignment">

So you could try to extend this 1000 threshold == I can but, same fear I also have that I would end-up with lot of variants.
dont require Type specific merges and see if that helps == I can't, since its not right way to do, i guess. Also you have suggested would not do that...

I would ask if breakdancer is actually calling the right DUP??
You are right actually !! It was unknown type but visualizing via IGV lead me to change this into DUP type.

Same for 10x genomics: 322kbp apart!
It is actually true, I have seen by their loupe (find the attachment) and IGV using bam.

Do you know the location of the DUP since it is a control?
C57BL/6J-Rorb	chr19	19,010,565	19,336,747	DUP	300kb
Thanking you for your explanations and time.
Rupesh

Hi Rupesh,
At 1) Yes SVType2 is not considered. Its the first time I see someone specify two different SVTypes...
At 2)  Ah you are right @10x . It should merge it, but the types are different and I think you ask for the matching types.
At 3) Try it. (No type save matches). As long as you keep the 1kbp distance it should not be bad.

We are getting there :)
Cheers
Fritz

Thanks Fritz for your time
@3.
Ok will try that  (No type save matches) but also I am trying to convert 10X vcf to format as other vcf so that SURVIVOR can take it.
Lets see what works for me, will update you soon.

Hi Fritz,
Just a quick question about SURVIVOR merge.
Does Order of tags are matters in VCF while using SURVIVOR merge? Since survivor requires START, END, SVTYPE and SVLEN.
Lets say

## breakdancer
chr19	19049089	.	.	.	.	PASS	PROGRAM=breakdancer;SVTYPE=DUP;SVLEN=304826;END=19353915	GT:DP	1/.:0

Can be (just converted tenX vcf similar to breakdancer)

chr1	3390039	call_2587_1	A	<DUP>	3	LOWQ	PROGRAM=TenX;END=3445262;SVLEN=55223;SVTYPE=DUP	GT	1|1
chr1	3445262	call_2587_2	T	<DUP>	3	LOWQ	PROGRAM=TenX;END=3390039;SVLEN=-55223;SVTYPE=DUP	GT	1|1

Thanks Rupesh

No the order should not matter within the INFO field.
Thats what you are asking right?
Cheers
Fritz

Yes that i was asking....
Now finally its working 👍 i.e SURVIVOR merge is now able to take 10X, delay and lumpy within 1K base apart of SVs.

chr19	19010558	call_285_1	G	<DUP>	23	PASS	SUPP=3;SUPP_VEC=0111;SVLEN=326003;SVTYPE=DUP;SVMETHOD=SURVIVOR1.0.7;CHR2=chr19;END=19336749;CIPOS=0,25;CIEND=-258,0;STRANDS=-+	GT:PSV:LN:DR:ST:QV:TY:ID:RAL:AAL:CO	./.:NaN:0:0,0:--:NaN:NaN:NaN:NAN:NAN:NAN	0/1:NA:325910:109,0:-+:.:DUP:DUP00041058:NA:NA:chr19_19010583-chr19_19336493	1|1:NA:326191:0,0:-+:23:DUP:call_285_1:NA:NA:chr19_19010558-chr19_19336749	./.:NA:325909:0,34:-+:.:DUP:134213:NA:NA:chr19_19010582-chr19_19336491

Thanks Fritz for informative discussion and guidance.
Rupesh

Awesome. Thanks for keeping me posted.
I will close the issue now.
Cheers
Fritz

Another updates:
By the way i tired with NO SVTYPE option and end-up with around 100 of SVs more integrated than converted vcf.
Plus i found difference between without SVTYPE  and with SVTYPE (using modified vcf) is that both have different START and END coordinates.
NO SVTYPE (from original vcf)
Number of integrated vcf: 5281
# start and end taken from lumpy
samples list:
10XSV.sort.vcf
breakDRorb_hstp_GT17-02247-MP.vcf
dellyRorb_hstp_GT17-02247-MP.vcf
lumpyRorb_hstp_GT17-02247-MP.vcf

chr19	19010583	DUP00041058	T		<DUP>	23	PASS	SUPP=3;SUPP_VEC=1011;SVLEN=326003;SVTYPE=DUP;SVMETHOD=SURVIVOR1.0.7;CHR2=chr19;END=19336493;CIPOS=-25,0;CIEND=-2,256;STRANDS=-+	GT:PSV:LN:DR:ST:QV:TY:ID:RAL:AAL:CO	1|1:NA:326191:0,0:++:23:INV:call_285_1:NA:NA:chr19_19010558-chr19_19336749	./.:NaN:0:0,0:--:NaN:NaN:NaN:NAN:NAN:NAN 0/1:NA:325910:109,0:-+:.:DUP:DUP00041058:NA:NA:chr19_19010583-chr19_19336493	./.:NA:325909:0,34:-+:.:DUP:134213:NA:NA:chr19_19010582-chr19_19336491

With SVTYPE (modified vcf)
Number of integrated vcf: 5185
# start and end taken from 10X
samples list:
breakDRorb_hstp_GT17-02247-MP.vcf
dellyRorb_hstp_GT17-02247-MP.vcf
lumpyRorb_hstp_GT17-02247-MP.vcf
refromated_Ten10X.sort.vcf

chr19	19010558	call_285_1	G	<DUP>	23	PASS	SUPP=3;SUPP_VEC=0111;SVLEN=326003;SVTYPE=DUP;SVMETHOD=SURVIVOR1.0.7;CHR2=chr19;END=19336749;CIPOS=0,25;CIEND=-258,0;STRANDS=-+	GT:PSV:LN:DR:ST:QV:TY:ID:RAL:AAL:CO	./.:NaN:0:0,0:--:NaN:NaN:NaN:NAN:NAN:NAN	0/1:NA:325910:109,0:-+:.:DUP:DUP00041058:NA:NA:chr19_19010583-chr19_19336493	1|1:NA:326191:0,0:-+:23:DUP:call_285_1:NA:NA:chr19_19010558-chr19_19336749	./.:NA:325909:0,34:-+:.:DUP:134213:NA:NA:chr19_19010582-chr19_19336491

Any idea why it is so ? I know it is not big difference in numbers as well as coordinates since it is set to 1K bp distance but i just want to know why it is happening ?
is it based on sample list or any specific reason ?
Thanks

Hi,
can you explain what you mean: "100 of SVs more integrated than converted vcf."
About the different locations: yes they are slightly different because it is always a best guess from all the evidence but a real coordinate. You can see that different sets were merged and also 3 calls. So it can change slightly, which it does.
What it does under the hood is to compute which of the locations is the median location for the start and it chooses this as a representative.
Makes sense?
Cheers
Fritz

Yes Fritz that makes sense thanks for your expansions.
And about number, I mean when i used NO SVTYPE on original vcf + delay and lumpy+breakdancer, i got more integrated vcfs (i guess, its because of no accurate SVTYPE has matched).

case 1 (NO SVTYPE has chosen and used original 10X vcf)
Number of integrated vcf: 5281

case 2 (SVTYPE has chosen and used modified 10X vcf)
Number of integrated vcf: 5185

5281-5185 = 96
I tired with only one sample and i am afraid that number can be increased in another samples. Since i have to merge around 60 samples.
Rupesh.

There can be some hickups wiht unsorted files. I usually only see them in larger populations.
Maybe this is what you are running into.
Thanks for pointing it out.
Fritz


ConnectionError: HTTPSConnectionPool(host='bitcointalk.org', port=443): Max retries exceeded with url: /index.php?action=profile;u=689228;sa=showPosts;start=0 (Caused by NewConnectionError('<urllib3.connection.VerifiedHTTPSConnection object at 0x7f5e1dbc2

View details in Rollbar: https://rollbar.com/vlabs/Venue/items/43/
Traceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/celery/app/trace.py", line 375, in trace_task
    R = retval = fun(*args, **kwargs)
  File "/usr/local/lib/python3.6/site-packages/celery/app/trace.py", line 632, in __protected_call__
    return self.run(*args, **kwargs)
  File "/code/venue/tasks.py", line 166, in scrape_forum_profile
    start=posts_scrape_start.replace(tzinfo=None)
  File "/code/venue/scrapers/bitcointalk.py", line 343, in scrape_posts
    posts = scraper.scrape_posts(forum_user_id, **kwargs)
  File "/code/venue/scrapers/bitcointalk.py", line 249, in scrape_posts
    resp = requests.get(url)
  File "/usr/local/lib/python3.6/site-packages/requests/api.py", line 72, in get
    return request('get', url, params=params, **kwargs)
  File "/usr/local/lib/python3.6/site-packages/requests/api.py", line 58, in request
    return session.request(method=method, url=url, **kwargs)
  File "/usr/local/lib/python3.6/site-packages/requests/sessions.py", line 508, in request
    resp = self.send(prep, **send_kwargs)
  File "/usr/local/lib/python3.6/site-packages/requests/sessions.py", line 618, in send
    r = adapter.send(request, **kwargs)
  File "/usr/local/lib/python3.6/site-packages/requests/adapters.py", line 508, in send
    raise ConnectionError(e, request=request)
ConnectionError: HTTPSConnectionPool(host='bitcointalk.org', port=443): Max retries exceeded with url: /index.php?action=profile;u=689228;sa=showPosts;start=0 (Caused by NewConnectionError('<urllib3.connection.VerifiedHTTPSConnection object at 0x7f5e1dbc2198>: Failed to establish a new connection: [Errno 101] Network unreachable',))Traceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/requests/adapters.py", line 440, in send
    timeout=timeout
  File "/usr/local/lib/python3.6/site-packages/urllib3/connectionpool.py", line 639, in urlopen
    _stacktrace=sys.exc_info()[2])
  File "/usr/local/lib/python3.6/site-packages/urllib3/util/retry.py", line 388, in increment
    raise MaxRetryError(_pool, url, error or ResponseError(cause))
MaxRetryError: HTTPSConnectionPool(host='bitcointalk.org', port=443): Max retries exceeded with url: /index.php?action=profile;u=689228;sa=showPosts;start=0 (Caused by NewConnectionError('<urllib3.connection.VerifiedHTTPSConnection object at 0x7f5e1dbc2198>: Failed to establish a new connection: [Errno 101] Network unreachable',))Traceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/urllib3/connectionpool.py", line 601, in urlopen
    chunked=chunked)
  File "/usr/local/lib/python3.6/site-packages/urllib3/connectionpool.py", line 346, in _make_request
    self._validate_conn(conn)
  File "/usr/local/lib/python3.6/site-packages/urllib3/connectionpool.py", line 850, in _validate_conn
    conn.connect()
  File "/usr/local/lib/python3.6/site-packages/urllib3/connection.py", line 284, in connect
    conn = self._new_conn()
  File "/usr/local/lib/python3.6/site-packages/urllib3/connection.py", line 150, in _new_conn
    self, "Failed to establish a new connection: %s" % e)
NewConnectionError: <urllib3.connection.VerifiedHTTPSConnection object at 0x7f5e1dbc2198>: Failed to establish a new connection: [Errno 101] Network unreachableTraceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/urllib3/connection.py", line 141, in _new_conn
    (self.host, self.port), self.timeout, **extra_kw)
  File "/usr/local/lib/python3.6/site-packages/urllib3/util/connection.py", line 83, in create_connection
    raise err
  File "/usr/local/lib/python3.6/site-packages/urllib3/util/connection.py", line 73, in create_connection
    sock.connect(sa)
OSError: [Errno 101] Network unreachable

I see no error in logdna, which is annoying and difficult to debug.
Also, it seems to be only this user. That seems odd.
As @realrhys points out, we're only seeing this in Dev, but we should still understand what is going on, if there's a code improvement possible.

That's not difficult to debug: OSError: [Errno 101] Network unreachable is pretty clear to me this is about bitcointalk.org not being reachable at the time that particular request was sent.
I agree though that more concise log of which part of the scraping actually failed should have been logged in LogDNA. I'll work on that.


Multiplayer Sync - Client-side Interpolation of other player's positions

I'll be tackling this one next.

Some references for myself:
http://gafferongames.com/networking-for-game-programmers/what-every-programmer-needs-to-know-about-game-networking/
http://buildnewgames.com/real-time-multiplayer/

Created two children tasks: #76 and #77


Prevent ICE when formatting braced vec! when...

Prevent ICE when formatting braced vec! when...
... it contains only items.
Fixes #5735
Attempting to format invocations of macros which are considered "forced
bracket macros" (currently only vec!), but are invoked with braces
instead of brackets, and contain only items in their token trees,
currently trigger an ICE in rustfmt. This is because the function that
handles formatting macro invocations containing only items,
rewrite_macro_with_items, assumes that the 'new' delimiter style of
the macro being formatted is the same as the delimiter style in the
source text when attempting to locate the span after the macro's opening
delimiter. This leads to the construction of an invalid span, triggering
the ICE.
The fix here is to pass the old delimiter style to
rewrite_macro_with_items as well, so that it can successfully locate
the span.

Hi rustfmt'ers! I'm back again with another ICE fix. Some notes for the reviewer:

With how I've implemented this fix, the original reproducing case

fn find_errors(mut self) {
	let errors: Vec<> = vec!{
		#[debug_format = "A({})"]
		struct A {}
	};
}

will be formatted into
fn find_errors(mut self) {
    let errors: Vec = vec![
        #[debug_format = "A({})"]
        struct A {}
    ];
}

I understand that the team's stance is that braced macro invocations should generally be left unformatted. However, the current behaviour of rustfmt on braced macro invocations that contain a mix of items and non-items, including vec!{...}, is to format them. That is, before this PR, rustfmt will turn vec!{1, struct X {} } into vec![1, struct X {}];.
My PR doesn't change this behaviour. It just extends a similar behaviour to vec! invocations that contain only items. So with my PR, whereas formatting vec!{ struct X {} } would previously have triggered an ICE, it's now formatted into
vec![
    struct X {}
];

I'm definitely not convinced that this is the 'right' direction to go in, but the alternative of leaving braced, item-only vec! invocations unformatted seemed about equally surprising to me from a user perspective. Any feedback here is appreciated, and I'm happy to tweak the implementation to whatever behaviour the team thinks is best.

I've also included a small refactoring commit of some redundancy I noticed while working in macros.rs. I'm happy to split that off into a separate PR if that's what people prefer.

Clippy isn't happy that I've added another parameter to rewrite_macro_with_items, pushing it over the threshold of 7 parameters. I didn't see a way to cleanly keep it below the threshold while still passing in the original delimiter style, but as usual any suggestions are appreciated.

Closing and resubmitting because I realized I misnamed the branch!


[WARN] Cannot resolve link to   in class Blah

Command:
$ /Users/balupton/Projects/taskgroup/node_modules/biscotto/bin/biscotto -n TaskGroup --title "TaskGroup API Documentation" -r README.md -o docs src - LICENSE.md HISTORY.md
[WARN] Cannot resolve link to
 in class Task
[WARN] Cannot resolve link to
 in class Task
[WARN] Cannot resolve link to
 in class Task
Parsed files:           6
Classes:                2 (0 undocumented)
Mixins:                 0
Non-Class files:        0
Methods:               45 (0 undocumented)
Constants:              0 (0 undocumented)
 100.00% documented (47 total, 0 with no doc)
 3 errors

The problem is that error message is not very helpful, it doesn't tell me what or where I should be looking.
File is from bevry/taskgroup:
# Import
queue = global?.setImmediate or process.nextTick  # node 0.8 b/c
events = require('events')
domain = (try require('domain')) ? null
util = require('util')
{EventEmitter} = require('events')
ambi = require('ambi')
csextends = require('csextends')
wait = (delay, fn) -> setTimeout(fn, delay)

# =====================================
# Interface

# Internal: Base class containing common functionality for {Task} and {TaskGroup}.
class Interface extends EventEmitter

	# Adds support for the done event while
	# ensuring that errors are always handled correctly.
	#
	# It does this by listening to the `error` and `completed` events,
	# and when the emit, we check if there is a `done` listener:
	# - if there is, then emit the done event with the original event arguments
	# - if there isn't, then output the error to stderr and throw it.
	constructor: ->
		super
		me = @

		# Add support for the done event
		# If we do have an error, then throw it if there is no existing or done listeners
		@on 'error', (args...) ->
			err = args[0]
			if me.listeners('done').length isnt 0  # has done listener, forward to that
				@emit('done', args...)
			else if err and me.listeners('error').length is 1  # has error, but no done listener and no event listener, throw err
				# this isn't good enough, throw the error
				console.error(err.stack or err)
				throw err

		@on 'completed', (args...) ->
			err = args[0]
			if me.listeners('done').length isnt 0  # has done listener, forward to that
				@emit('done', args...)
			else if err and me.listeners('completed').length is 1  # has error, but no done listener and no event listener, throw err
				# this isn't good enough, throw the error
				console.error(err.stack or err)
				throw err

		# Chain
		@

	# Internal: Fire our completion event.
	complete: ->
		err = throw Error('interface should provide this')
		@emit('error', err)
		@

	# Public: Attaches the listener to the `done` event to be emitted each time.
	#
	# listener - The {Function} to attach to the `done` event.
	whenDone: (listener) ->
		# check if we have a listener
		if typeof listener is 'function'
			@on('done', listener.bind(@))

		# Chain
		@

	# Public: Attaches the listener to the `done` event to be emitted only once, then removed to not fire again.
	#
	# listener - The {Function} to attach to the `done` event.
	onceDone: (listener) ->
		# check if we have a listener
		if typeof listener is 'function'
			@once('done', listener)

		# Chain
		@

	# Public: Alias for {::onceDone}
	done: (args...) ->
		return @onceDone(args...)

	# Public: Get our name with all of our parent names into a {String} or {Array}.
	#
	# opts - The options
	#        :format - (default: 'string') A {String} that determines the format that we return, when `string` it will output a string of all our names, when `array` it will return the names as an array
	#        :seperator - (default: ' ➞  ') A {String} that is used to join our array when returning a joined {String}
	#
	# Returns either a joined {String} or an {Array} based on the value of the `format` option.
	getNames: (opts={}) ->
		# Prepare
		opts.format ?= 'string'
		opts.separator ?= ' ➞  '

		# Fetch
		names = @config.parent?.getNames(format: 'array') or []
		names.push(name)  if name = @getName()

		# Format
		if opts.format isnt 'array'
			names = names.join(opts.separator)

		# Return
		return names

	# Public: Get the name of our instance.
	#
	# If the name was never configured, then return the name in the format of
	# `'#{@type} #{Math.random()}'` to output something like `task 0.2123`
	#
	# Returns the configured name {String}.
	getName: ->
		return @config.name ?= "#{@type} #{Math.random()}"

	# Public: Get the configuration of our instance.
	#
	# Returns our configuration {Object} directly.
	getConfig: -> @config

# =====================================

# Public: Our Task Class.
#
# Available configuration is documented in {::setConfig}.
#
# Available events:
#
# - `started()` - emitted when we start execution
# - `running()` - emitted when the method starts execution
# - `failed(err)` - emitted when execution exited with a failure
# - `passed()` - emitted when execution exited with a success
# - `completed(err, args...)` - emitted when execution exited, `args` are the result arguments from the method
# - `error(err)` - emtited if an unexpected error occurs without ourself
# - `done(err, args...)` - emitted when either execution completes (the `completed` event) or when an unexpected error occurs (the `error` event)
#
# Available internal statuses:
#
# - `null` - execution has not yet started
# - `'started'` - execution has begun
# - `'running'` - execution of our method has begun
# - `'failed'` - execution of our method has failed
# - `'passed'` - execution of our method has succeeded
# - `'destroyed'` - we've been destroyed and can no longer execute
#
# Examples
#
#  task = require('taskgroup').Task.create('my synchronous task', function(){
#    return 5
#  }).done(console.log)  // [null, 5]
#
#  task = require('taskgroup').Task.create('my asynchronous task', function(complete){
#    complete(null, 5)
#  }).done(console.log)  // [null, 5]
#
#  task = require('taskgroup').Task.create('my task that errors', function(){
#    var err = new Error('deliberate error')
#    return err;  // if asynchronous, can also do: complete(err)
#    // thrown and uncaught errors are also caught thanks to domains, but that should be avoided
#    // as it would put your app in an unknown state
#  }).done(console.log)  // [Error('deliberator error')]
class Task extends Interface
	# Internal: The type of our class for the purpose of duck typing
	# which is needed when working with node virtual machines
	# as instanceof will not work in those environments.
	type: 'task'

	# Public: A helper method to check if the passed argument is an instanceof a {Task}.
	#
	# item - The possible instance of the {Task} that we want to check
	#
	# Returns a {Boolean} of whether or not the item is a {Task} instance.
	@isTask: (item) -> return item?.type is 'task' or item instanceof Task

	# Public: A helper method to create a new subclass with our extensions.
	#
	# extensions - An {Object} of extensions to apply to the new subclass
	#
	# Returns the new sub {Class}
	@subclass: csextends

	# Public: Creates a new {Task} instance.
	#
	# args - The Arguments to forwarded along to the {::constructor}.
	#
	# Returns the new {Task} instance.
	@create: (args...) -> return new @(args...)

	# Internal: The first {Error} that has occured.
	err: null

	# Internal: An {Array} of the result arguments of our method.
	# The first item in the array should be the {Error} if it exists.
	result: null

	# Internal: A {String} containing our current status. See our {Task} description for available values.
	status: null

	# Internal: An {Array} of the events that we may emit. Events that will be executed can be found in the {Task} description.
	events: null

	# Internal: The {Domain} that we create to capture errors for our method.
	taskDomain: null

	# Internal: The configuration for our {Task} instance. See {::setConfig} for available configuration.
	config: null

	# Public: Initialize our new {Task} instance. Forwards arguments onto {::setConfig}.
	constructor: (args...) ->
		super

		# Prepare
		@config ?= {}
		@config.run ?= false
		@config.onError ?= 'exit'
		@config.ambi ?= true
		@config.domain ?= true
		@events ?= []
		@events.push('error', 'started', 'running', 'failed', 'passed', 'completed', 'done', 'destroyed')

		# Apply configuration
		@setConfig(args)

		# Chain
		@

	# Public: Set the configuration for our instance.
	#
	# Despite accepting an {Object} of configuration, we can also accept an {Array} of configuration.
	# When using an array, a {String} becomes the :name, a {Function} becomes the :method, and an {Object} becomes the :config
	#
	# config - Our configuration {Object} can contain the following fields:
	#   :name - (default: null) A {String} for what we would like our name to be, useful for debugging.
	#   :done - (default: null) A {Function} that we would like passed to {::onceDone} (aliases are :onceDone, and :next)
	#   :whenDone - (default: null) A {Function} that we would like passed to {::whenDone}
	#   :on - (default: null) An {Object} of (eventName => listener) that we would like bound via EventEmitter.on.
	#   :once - (default: null) An {Object} of (eventName => listener) that we would like bound via EventEmitter.once.
	#   :method - (default: null) The {Function} that we would like to execute within our task.
	#   :parent - (default: null) A parent {TaskGroup} that we may be attached to.
	#   :onError - (default: 'exit') A {String} that is either `'exit'` or `'ignore'`, when `'ignore'` duplicate run errors are not reported, useful when combined with the timeout option.
	#   :args - (default: null) An {Array} of arguments that we would like to forward onto our method when we execute it.
	#   :timeout - (default: null) A {Number} of millesconds that we would like to wait before timing out the method.
	#   :ambi - (default: true) A {Boolean} for whether or not to use bevry/ambi to determine if the method is asynchronous or synchronous and execute it appropriately
	#   :domain - (default: true) A {Boolean} for whether or not to wrap the task execution in a domain to attempt to catch background errors (aka errors that are occuring in other ticks than the initial execution)
	setConfig: (opts={}) ->
		# Handle arguments
		if Array.isArray(opts)
			# Prepare configuration
			args = opts
			opts = {}

			# Extract the configuration from the arguments
			for arg in args
				continue  unless arg
				switch typeof arg
					when 'string'
						opts.name = arg
					when 'function'
						opts.method = arg
					when 'object'
						for own key,value of arg
							opts[key] = value

		# Apply the configuration directly to our instance
		for own key,value of opts
			switch key
				when 'on'
					for own _key,_value of value
						@on(_key, _value)  if value

				when 'once'
					for own _key,_value of value
						@once(_key, _value)  if value

				when 'whenDone'
					@whenDone(value)  if value

				when 'onceDone', 'done', 'next'
					@done(value)  if value

				else
					@config[key] = value

		# Chain
		@

	# Public: Have we started execution yet?
	#
	# Returns a {Boolean} which is `true` if we have commenced execution
	hasStarted: ->
		return @status isnt null

	# Public: Have we finished its execution yet?
	#
	# Returns a {Boolean} which is `true` if we have finished execution
	hasExited: ->
		return @status in ['completed', 'destroyed']

	# Public: Have we been destroyed?
	#
	# Returns a {Boolean} which is `true` if we have bene destroyed
	isDestroyed: ->
		return @status is 'destroyed'

	# Public: Have we completed its execution yet?
	#
	# Returns a {Boolean} which is `true` if we have completed
	isComplete: ->
		return @status in ['failed', 'passed', 'destroyed']

	# Internal: Handles the completion and error conditions for ourself.
	#
	# Should only ever execute once, if it executes more than once, then we error.
	#
	# args - The arguments {Array} that will be applied to the {::result} variable. First argument is the {Error} if it exists.
	exit: (args...) ->
		# Store the first error
		@err ?= args[0]  if args[0]?

		# Complete for the first (and hopefully only) time
		if @isComplete() is false
			# Apply the result if it exists
			if args.length isnt 0
				@result = args

			# Did we error?
			@status = (if @err? then 'failed' else 'passed')

			# Notify our listeners of our status
			@emit(@status, @err)

			# Finish up
			@complete()

		# Error as we have already completed before
		else if @config.onError isnt 'ignore'
			err = new Error """
				The task [#{@getNames()}] just completed, but it had already completed earlier, this is unexpected. State information is:
				#{util.inspect({error:@err, previousResult:@result, currentArguments:args})}
				"""
			@emit('error', err)

		# Chain
		@

	# Internal: Completetion Emitter. Used to emit the `completed` event and to cleanup our state.
	complete: ->
		complete = @isComplete()

		if complete
			# Notify our listeners we have completed
			@emit 'completed', (@result or [])...

			# Prevent the error from persisting
			@err = null

			# Should we reset results?
			# @results = []
			# no, it would break the promise nature of done
			# as it would mean that if multiple done listener are added, they would each get different results
			# if they wish to reset the results, they should do so manually via resetResults

			# Should we reset the status?
			# @status = null
			# no, it would break the promise nature of done
			# as it would mean that once a done is fired, no more can be fired, until run is called again

		return complete

	# Public: When Done Promise.
	# Fires the listener, either on the next tick if we are already done, or if not, each time the `done` event fires.
	#
	# listener - The {Function} to attach or execute.
	whenDone: (listener) ->
		if @isComplete()
			queue =>  # avoid zalgo
				listener.apply(@, @result or [])
		else
			super(listener)
		@

	# Public: Once Done Promise.
	# Fires the listener once, either on the next tick if we are already done, or if not, once the `done` event fires.
	#
	# listener - The {Function} to attach or execute.
	onceDone: (listener) ->
		if @isComplete()
			queue =>  # avoid zalgo
				listener.apply(@, @result or [])
		else
			super(listener)
		@

	# Internal: Reset the results.
	#
	# At this point this method is internal, as it's functionality may change in the future, and it's outside use is not yet confirmed. If you need such an ability, let us know via the issue tracker.
	resetResults: ->
		@result = []
		@

	# Public: Destroy the task and prevent it from executing ever again.
	destroy: ->
		@done =>
			# Are we already destroyed?
			return  if @status is 'destroyed'

			# Update our status and notify our listeners
			@emit(@status = 'destroyed')

			# Clear results
			@resetResults()
			# item arrays should already be wiped due to done completion

			# Remove all isteners
			# @TODO should we exit or dispose of the domain?
			@removeAllListeners()

		# Chain
		@

	# Internal: Fire the task method with our config arguments and wrapped in a domain.
	fire: ->
		# Prepare
		me = @
		args = (@config.args or []).slice()

		# Check that we have a method to fire
		if me.config.method?.bind? is false
			err = new Error """
				The task [#{me.getNames()}] failed to run as no method was defined for it.
				"""
			me.emit('error', err)
			return @

		# Prepare the task domain if it doesn't already exist
		if @config.domain isnt false and @taskDomain? is false and domain?.create?
			# Setup the domain
			@taskDomain = domain.create()
			@taskDomain.on('error', @exit.bind(@))

			# Make sure if the method supports a callback, we prevent the domain from entering our task
			# RE: https://github.com/bevry/taskgroup/issues/17
			complete = (args...) ->
				me.taskDomain?.exit()
				return me.exit(args...)
		else
			complete = @exit.bind(@)

		# Our fire function that will be wrapped in a domain or executed directly
		fireMethod = ->
			# Bind the method to ourself
			methodToFire = me.config.method.bind(me)

			# Execute with ambi if appropriate
			if me.config.ambi isnt false
				ambi(methodToFire, args...)

			# Otherwise execute directly if appropriate
			else
				methodToFire(args...)

		# Setup timeout if appropriate
		if me.config.timeout
			me.timeout = wait me.config.timeout, ->
				if me.isComplete() is false
					err = new Error """
						The task [#{me.getNames()}] has timed out.
						"""
					me.exit(err)

		# Notify that we are now running
		me.emit(me.status = 'running')

		# Check for crippled domain and use try...catch instead
		if process.browser or process.versions.node.substr(0,3) is '0.8'
			# Use the next tick workaround to escape the try...catch scope
			# Which would otherwise catch errors inside our code when it shouldn't therefore suppressing errors
			completeOriginal = complete
			complete = (args...) ->
				process.nextTick -> completeOriginal(args...)
				return me

			# Add the competion callback to the arguments our method will receive
			args.push(complete)

			# Wrap in a try...catch to at least provide some protection
			try
				# Fire the method within the domain if desired, otherwise execute directly
				if @taskDomain? then @taskDomain.run(fireMethod) else fireMethod()
			catch err
				me.exit(err)
		else
			# Add the competion callback to the arguments our method will receive
			args.push(complete)

			# Fire the method within the domain if desired, otherwise execute directly
			if @taskDomain? then @taskDomain.run(fireMethod) else fireMethod()

		# Chain
		@

	# Public: Start the execution of the task.
	#
	# Will emit an `error` event if the task has already started before.
	run: ->
		queue =>
			# Already completed or even destroyed?
			if @hasStarted()
				err = new Error """
					The task [#{@getNames()}] was just about to start, but it already started earlier, this is unexpected.
					"""
				@emit('error', err)

			# Not yet completed, so lets run!
			else
				# Apply our new status and notify our listeners
				@emit(@status = 'started')

				# Fire the task
				@fire()

		# Chain
		@

# =====================================
# Task Group

# Public: Our TaskGroup class.
#
# Available configuration is documented in {::setConfig}.
#
# Available events:
# - `started()` - emitted when we start execution
# - `running()` - emitted when the first item starts execution
# - `failed(err)` - emitted when execution exited with a failure
# - `passed()` - emitted when execution exited with a success
# - `completed(err, results)` - emitted when execution exited, `results` is an {Array} of the result arguments for each item that executed
# - `error(err)` - emtited if an unexpected error occured within ourself
# - `done(err, results)` - emitted when either the execution completes (the `completed` event) or when an unexpected error occurs (the `error` event)
# - `item.*(...)` - bubbled events from an added item
# - `task.*(...)` - bubbled events from an added {Task}
# - `group.*(...)` - bubbled events from an added {TaskGroup}
#
# Available internal statuses:
# - `null` - execution has not yet started
# - `'started'` - execution has begun
# - `'running'` - execution of items has begun
# - `'failed'` - execution has exited with failure status
# - `'passed'` - execution has exited with success status
# - `'destroyed'` - we've been destroyed and can no longer execute
class TaskGroup extends Interface
	# Internal: The type of our class for the purpose of duck typing
	# which is needed when working with node virtual machines
	# as instanceof will not work in those environments.
	type: 'taskgroup'

	# Public: A helper method to check if the passed argument is an instanceof a {TaskGroup}.
	#
	# item - The possible instance of the {TaskGroup} that we want to check
	#
	# Returns a {Boolean} of whether or not the item is a {TaskGroup} instance.
	@isTaskGroup: (group) -> return group?.type is 'taskgroup' or group instanceof TaskGroup

	# Public: A helper method to create a new subclass with our extensions.
	#
	# extensions - An {Object} of extensions to apply to the new subclass
	#
	# Returns the new sub {Class}
	@subclass: csextends

	# Public: Creates a new {TaskGroup} instance.
	#
	# args - The Arguments to be forwarded along to the {::constructor}.
	#
	# Returns the new {TaskGroup} instance.
	@create: (args...) -> return new @(args...)

	# Internal: An {Array} of the items that are still yet to execute
	itemsRemaining: null

	# Internal: An {Array} of the items that are currently running
	itemsRunning: null

	# Internal: An {Array} of the items that have completed
	itemsCompleted: null

	# Internal: An {Array} of the result Arguments for each completed item when their :includeInResults configuration option is not `false`
	results: null

	# Internal: An {Error} object if execution has failed at some point
	err: null

	# Internal: A {String} containing our current status. See our {Task} description for available values.
	status: null

	# Internal: An {Array} of the events that we may emit. Events that will be executed can be found in the {Task} description.
	events: null

	# Internal: The configuration for our {Task} instance. See {::setConfig} for available configuration.
	config: null

	# Public: Initialize our new {TaskGroup} instance. Forwards Arguments onto {::setConfig}.
	constructor: (args...) ->
		# Init
		me = @
		super
		@config ?= {}
		@config.concurrency ?= 1
		@config.onError ?= 'exit'
		@itemsRemaining ?= []
		@itemsRunning ?= []
		@itemsCompleted ?= []
		@results ?= []
		@events ?= []
		@events.push('error', 'started', 'running', 'passed', 'failed', 'completed', 'done', 'destroyed')

		# Apply configuration
		@setConfig(args)

		# Give setConfig enough chance to fire
		# Changing this to setImmediate breaks a lot of things
		# As tasks inside nested taskgroups will fire in any order
		queue(@autoRun.bind(@))

		# Chain
		@

	# ---------------------------------
	# Configuration

	# Public: Set Nested Task Config
	setNestedTaskConfig: (config={}) ->
		@config.nestedTaskConfig ?= {}
		for own key,value of config
			@config.nestedTaskConfig[key] = value
		@

	# Public: Set Nested Config
	setNestedConfig: (config={}) ->
		@setConfig(config)
		@config.nestedConfig ?= {}
		for own key,value of config
			@config.nestedConfig[key] = value
		@

	# Public: Set the configuration for our instance.
	#
	# Despite accepting an {Object} of configuration, we can also accept an {Array} of configuration.
	# When using an array, a {String} becomes the :name, a {Function} becomes the :method, and an {Object} becomes the :config
	#
	# config - Our configuration {Object} can contain the following fields:
	#   :name - (default: null) A {String} for what we would like our name to be, useful for debugging.
	#   :done - (default: null) A {Function} that we would like passed to {::onceDone} (aliases are :onceDone, and :next)
	#   :whenDone - (default: null) A {Function} that we would like passed to {::whenDone}
	#   :on - (default: null) An {Object} of (eventName => listener) that we would like bound via EventEmitter.on.
	#   :once - (default: null) An {Object} of (eventName => listener) that we would like bound via EventEmitter.once.	#   :method - (default: null) A {Function} that we would like to use to created nested groups and tasks using an inline style.
	#   :parent - (default: null) A parent {TaskGroup} that we may be attached to.
	#   :onError - (default: 'exit') A {String} that is either `'exit'` or `'ignore'`, when `'ignore'` errors that occur within items will not halt execution and will not be reported in the completion callbacks `err` argument (but will still be in the `results` argument).
	#   :concurrency - (default: 1) The {Number} of items that we would like to execute at the same time. Use `0` for unlimited. `1` accomplishes serial execution, everything else accomplishes parallel execution.
	#   :run - (default: true) A {Boolean} for whether or not to the :method (if specified) automatically.
	#   :nestedConfig - (default: null) An {Object} of nested configuration to be applied to all items of this group.
	#   :nestedTaskConfig - (default: null) An {Object} of nested configuration to be applied to all {Task}s of this group.
	#   :tasks - (default: null) An {Array} of tasks to be added as children.
	#   :groups - (default: null) An {Array} of groups to be added as children.
	#   :items - (default: null) An {Array} of {Task} and/or {TaskGroup} instances to be added to this group.
	setConfig: (opts={}) ->
		# Handle arguments
		if Array.isArray(opts)
			# Prepare configuration
			args = opts
			opts = {}

			# Extract the configuration from the arguments
			for arg in args
				continue  unless arg
				switch typeof arg
					when 'string'
						opts.name = arg
					when 'function'
						opts.method = arg
					when 'object'
						for own key,value of arg
							opts[key] = value

		# Apply the configuration directly to our instance
		for own key,value of opts
			switch key
				when 'on'
					for own _key,_value of value
						@on(_key, _value)  if value

				when 'once'
					for own _key,_value of value
						@once(_key, _value)  if value

				when 'whenDone'
					@whenDone(value)  if value

				when 'onceDone', 'done', 'next'
					@done(value)  if value

				when 'task', 'tasks'
					@addTasks(value)  if value

				when 'group', 'groups'
					@addGroups(value)  if value

				when 'item', 'items'
					@addItems(value)  if value

				else
					@config[key] = value

		# Chain
		@

	# ---------------------------------
	# TaskGroup Method

	# Internal: Prepare the method and it's configuration, and add it as a task to be executed.
	#
	# method - The {Function} of our method
	# config - An optional {Object} of configuration for the task to be created for our method
	addMethod: (method, config={}) ->
		method ?= @config.method.bind(@)
		method.isTaskGroupMethod = true
		config.name ?= 'taskgroup method for '+@getName()
		config.args ?= [@addGroup.bind(@), @addTask.bind(@)]
		config.includeInResults ?= false
		return @addTask(method, config)

	# Internal: Autorun ourself under certain conditions.
	#
	# Those conditions being:
	# - if we the :method configuration is defined, and we have no :parent
	# - if we the :run configuration is `true`
	#
	# Used primarily to cause the :method to fire at the appropriate time when using inline style.
	autoRun: ->
		# Auto run if we are going the inline style and have no parent
		if @config.method
			# Add the function as our first unamed task with the extra arguments
			item = @addMethod()

			# If we are the topmost group
			if @config.parent? is false
				# then run if possible
				@config.run ?= true

		# Auto run if we are configured to
		if @config.run is true
			@run()

		# Chain
		@

	# ---------------------------------
	# Add Item

	# Internal: Add an item to ourself and configure it accordingly
	#
	# item - A {Task} or {TaskGroup} instance that we would like added to ourself
	# args - Additional configuration Arguments to apply to each item
	addItem: (item, args...) ->
		# Prepare
		me = @

		# Only add the item if it exists
		return null  unless item

		# Link our item to ourself
		item.setConfig({parent: @})
		item.setConfig(args...)  if args.length isnt 0
		item.config.name ?= "#{item.type} #{@getItemsTotal()+1} for #{@getName()}"

		# Bubble task events
		if Task.isTask(item)
			# Nested configuration
<EMAIL_ADDRESS> if @config.nestedConfig?
<EMAIL_ADDRESS> if @config.nestedTaskConfig?

			item.events.forEach (event) ->
				item.on event, (args...) ->
					me.emit("task.#{event}", item, args...)

			# Notify our intention
			@emit('task.add', item)

		# Bubble group events
		else if TaskGroup.isTaskGroup(item)
			# Nested configuration
<EMAIL_ADDRESS> if @config.nestedConfig?
			item.setConfig(nestedTaskConfig: @config.nestedTaskConfig)  if @config.nestedTaskConfig?

			# Bubble item events
			item.events.forEach (event) ->
				item.on event, (args...) ->
					me.emit("group.#{event}", item, args...)

			# Notify our intention
			@emit('group.add', item)

		# Bubble item events
		item.events.forEach (event) ->
			item.on event, (args...) ->
				me.emit("item.#{event}", item, args...)

		###
		# Bubble item error event directly
		item.on 'error', (args...) ->
			me.emit('error', args...)
		###

		# Notify our intention
		@emit('item.add', item)

		# Handle item completion and errors once
		# we can't just do item.done, or item.once('done'), because we need the item to be the argument, rather than `this`
		item.done (args...) ->
			me.itemCompletionCallback(item, args...)

		# Add the item
		@itemsRemaining.push(item)

		# We may be running and expecting items, if so, fire
		@fire()

		# Return the item
		return item

	# Internal: Add items to ourself and configure them accordingly
	#
	# items - An {Array} of {Task} and/or {TaskGroup} instances to add to ourself
	# args - Optional Arguments to configure each added item
	addItems: (items, args...) ->
		items = [items]  unless Array.isArray(items)
		return (@addItem(item, args...)  for item in items)

	# ---------------------------------
	# Add Task

	# Public: Create a {Task} instance from some configuration.
	#
	# If the first argument is already a {Task} instance, then just update it's configuration with the remaning arguments.
	#
	# args - Arguments to use to configure the {Task} instance
	#
	# Returns the new {Task} instance
	createTask: (args...) ->
		# Support receiving an existing task instance
		if Task.isTask(args[0])
			task = args[0]
			task.setConfig(args.slice(1)...)

		# Support receiving arguments to create a task instance
		else
			task = new Task(args...)

		# Return the new task
		return task

	# Public: Add a {Task} with some configuration to ourself, create it if needed.
	#
	# args - Arguments to configure (and if needed, create) the task
	addTask: (args...) ->
		task = @addItem @createTask args...

		# Chain
		@

	# Public: Add {Task}s with some configuration to ourself, create it if needed.
	#
	# items - An {Array} of {Task} items to add to ourself
	# args - Optional Arguments to configure each added {Task}
	addTasks: (items, args...) ->
		items = [items]  unless Array.isArray(items)
		tasks = (@addTask(item, args...)  for item in items)

		# Chain
		@

	# ---------------------------------
	# Add Group

	# Public: Create a {TaskGroup} instance from some configuration.
	#
	# If the first argument is already a {TaskGroup} instance, then just update it's configuration with the remaning arguments.
	#
	# args - Arguments to use to configure the {TaskGroup} instance
	#
	# Returns the new {TaskGroup} instance
	createGroup: (args...) ->
		# Support recieving an existing taskgroup instance
		if TaskGroup.isTaskGroup(args[0])
			taskgroup = args[0]
			taskgroup.setConfig(args.slice(1)...)

		# Support receiving arugments to create a taskgroup intance
		else
			taskgroup = new TaskGroup(args...)

		# Return the taskgroup instance
		return taskgroup

	# Public: Add a {TaskGroup} with some configuration to ourself, create it if needed.
	#
	# args - Arguments to configure (and if needed, create) the {TaskGroup}
	addGroup: (args...) ->
		group = @addItem @createGroup args...

		# Chain
		@

	# Public: Add {TaskGroup}s with some configuration to ourself, create it if needed.
	#
	# items - An {Array} of {TaskGroup} items to add to ourself
	# args - Optional Arguments to configure each added {TaskGroup}
	addGroups: (items, args...) ->
		items = [items]  unless Array.isArray(items)
		groups = (@addGroup(item, args...)  for item in items)

		# Chain
		@

	# ---------------------------------
	# Status Indicators

	# Public: Gets the total number of items
	#
	# Returns a {Number} of the total items we have
	getItemsTotal: ->
		running = @itemsRunning.length
		remaining = @itemsRemaining.length
		completed = @itemsCompleted.length
		total = running + remaining + completed
		return total

	# Public: Gets the names of the items, the total number of items, and their results for the purpose of debugging.
	#
	# Returns an {Object} containg the hashes:
	#   :remaining - An {Array} of the names of the remaining items
	#   :running - An {Array} of the names of the running items
	#   :completed - An {Array} of the names of the completed items
	#   :total - A {Number} of the total items we have
	#   :results - An {Array} of the results of the compelted items
	getItemNames: ->
		running = @itemsRunning.map (item) -> item.getName()
		remaining = @itemsRemaining.map (item) -> item.getName()
		completed = @itemsCompleted.map (item) -> item.getName()
		results = @results
		total = running.length + remaining.length + completed.length
		return {
			remaining
			running
			completed
			total
			results
		}

	# Public: Gets the total number count of each of our item lists.
	#
	# Returns an {Object} containg the hashes:
	#   :remaining - A {Number} of the total remaining items
	#   :running - A {Number} of the total running items
	#   :completed - A {Number} of the total completed items
	#   :total - A {Number} of the total items we have
	#   :results - A {Number} of the total results we have
	getItemTotals: ->
		running = @itemsRunning.length
		remaining = @itemsRemaining.length
		completed = @itemsCompleted.length
		results = @results.length
		total = running + remaining + completed
		return {
			remaining
			running
			completed
			total
			results
		}

	# Public: Whether or not we have any running items
	#
	# Returns a {Boolean} which is `true` if we have any items that are currently running
	hasRunning: ->
		return @itemsRunning.length isnt 0

	# Public: Whether or not we have any items that are yet to execute
	#
	# Returns a {Boolean} which is `true` if we have any items that are still yet to be executed
	hasRemaining: ->
		return @itemsRemaining.length isnt 0

	# Public: Whether or not we have any items
	#
	# Returns a {Boolean} which is `true` if we have any running or remaining items
	hasItems: ->
		return @hasRunning() or @hasRemaining()

	# Public: Have we started execution yet?
	#
	# Returns a {Boolean} which is `true` if we have commenced execution
	hasStarted: ->
		return @status isnt null

	# Public
	hasResult: ->
		return @err? or @results.length isnt 0

	# Public: Have we finished its execution yet?
	#
	# Returns a {Boolean} which is `true` if we have finished execution
	hasExited: ->
		return @status in ['completed', 'destroyed']

	# Internal: Whether or not we have any available slots to execute more items.
	#
	# Returns a {Boolean} which is `true` if we have available slots.
	hasSlots: ->
		return (
			@config.concurrency is 0 or
			@itemsRunning.length < @config.concurrency
		)

	# Internal: Whether or not we have errord and want to pause when we have an error.
	#
	# Returns a {Boolean} which is `true` if we are paused.
	shouldPause: ->
		return (
			@config.onError is 'exit' and
			@err?
		)

	# Internal: Whether or not we are capable of firing more items.
	#
	# This is determined whether or not we are not paused, and we have remaning items, and we have slots able to execute those remaning items.
	#
	# Returns a {Boolean} which is `true` if we can fire more items.
	shouldFire: ->
		return (
			@shouldPause() is false and
			@hasRemaining() and
			@hasSlots()
		)

	# Public: Whether or not we have no items left
	#
	# Returns a {Boolean} which is `true` if we have no more running or remaining items
	isEmpty: ->
		return @hasItems() is false

	# Public
	isPaused: ->
		return (
			@shouldPause() and
			@hasRunning() is false
		)

	# Public: Have we completed its execution yet?
	#
	# Completion of executed is determined of whether or not we have started, and whether or not we are currently paused or have no remaining and running items left
	#
	# Returns a {Boolean} which is `true` if we have completed execution
	isComplete: ->
		return (
			@hasStarted() and
			(
				@isPaused() or
				@isEmpty()
			)
		)

	# ---------------------------------
	# Firers

	# Internal: Completetion Emitter. Used to emit the `completed` event and to cleanup our state.
	complete: ->
		complete = @isComplete()

		if complete
			# Notity our listners we have completed
			@emit('completed', @err, @results)

			# Prevent the error from persisting
			@err = null

			# Cleanup the items that will now go unused
			for item in @itemsCompleted
				item.destroy()
			@itemsCompleted = []

			# Should we reset results?
			# @results = []
			# no, it would break the promise nature of done
			# as it would mean that if multiple done handlers are added, they would each get different results
			# if they wish to reset the results, they should do so manually via resetResults

			# Should we reset the status?
			# @status = null
			# no, it would break the promise nature of done
			# as it would mean that once a done is fired, no more can be fired, until run is called again

		return complete

	# Public: When Done Promise.
	# Fires the listener, either on the next tick if we are already done, or if not, each time the `done` event fires.
	#
	# listener - The {Function} to attach or execute.
	whenDone: (handler) ->
		if @isComplete()
			queue =>  # avoid zalgo
				handler.call(@, @err, @results)
		else
			super(handler)
		@

	# Public: Once Done Promise.
	# Fires the listener once, either on the next tick if we are already done, or if not, once the `done` event fires.
	#
	# listener - The {Function} to attach or execute.
	onceDone: (handler) ->
		if @isComplete()
			queue =>  # avoid zalgo
				handler.call(@, @err, @results)
		else
			super(handler)
		@

	# Internal: Reset the results.
	#
	# At this point this method is internal, as it's functionality may change in the future, and it's outside use is not yet confirmed. If you need such an ability, let us know via the issue tracker.
	resetResults: ->
		@results = []
		@

	# Internal: Fire the next items.
	#
	# Returns either an {Array} items that was fired, or `false` if no items were fired.
	fireNextItems: ->
		items = []

		# Fire the next items
		while true
			item = @fireNextItem()
			if item
				items.push(item)
			else
				break

		result =
			if items.length isnt 0
				items
			else
				false

		return result

	# Internal: Fire the next item.
	#
	# Returns either the item that was fired, or `false` if no item was fired.
	fireNextItem: ->
		# Prepare
		result = false
		fire = @shouldFire()

		# Can we run the next item?
		if fire
			# Fire the next item

			# Update our status and notify our listeners
			@emit(@status = 'running')  if @status isnt 'running'

			# Get the next item and remove it from the remaining items
			item = @itemsRemaining.shift()
			@itemsRunning.push(item)

			# Run it
			item.run()

			# Return the item
			result = item

		# Return
		return result

	# Internal: What to do when an item completes
	itemCompletionCallback: (item, args...) ->
		# Update error if it exists
		@err ?= args[0]  if @config.onError is 'exit' and args[0]

		# Mark that one less item is running
		index = @itemsRunning.indexOf(item)
		if index is -1
			# this should never happen, but maybe it could, in which case we definitely want to know about it
			@err ?= indexError = new Error("Could not find [#{item.getNames()}] in the running queue")
			console.error(indexError.stack or indexError)
		else
			@itemsRunning = @itemsRunning.slice(0, index).concat(@itemsRunning.slice(index+1))

		# Add to the completed queue
		@itemsCompleted.push(item)

		# Add the result
		@results.push(args)  if item.config.includeInResults isnt false

		# Fire
		@fire()

		# Chain
		@

	# Internal: Either execute the reamining items we are not paused, or complete execution by exiting.
	fire: ->
		# Have we actually started?
		if @hasStarted()
			# Check if we are complete, if so, exit
			if @isComplete()
				@exit()

			# Otherwise continue firing items if we are wanting to pause
			else if @shouldPause() is false
				@fireNextItems()

		# Chain
		@

	# Public: Clear remaning items.
	clear: ->
		# Destroy all the items
		for item in @itemsRemaining
			item.destroy()
		@itemsRemaining = []

		# Chain
		@

	# Public: Destroy all remaining items and remove listeners.
	destroy: ->
		# Destroy all the items
		@clear()

		# Once finished, destroy it
		@done =>
			# Are we already destroyed?
			return  if @status is 'destroyed'

			# Apply our new status and notify our listeners
			@emit(@status = 'destroyed')

			# Clear results
			@resetResults()
			# item arrays should already be wiped due to done completion

			# Remove listeners
			@removeAllListeners()

		# Chain
		@

	# Internal: We now want to exit.
	exit: (err) ->
		# Update error if set
		@err ?= err  if err?

		# Update the status
		@status = (if @err? then 'failed' else 'passed')

		# Notify our listeners
		@emit(@status, @err)

		# Fire the completion callback
		@complete()

		# Chain
		@

	# Public: Start the execution.
	run: (args...) ->
		queue =>
			# Apply our new status and notify our intention to run
			@emit(@status = 'started')

			# Give time for the listeners to complete before continuing
			@fire()

		# Chain
		@

# Export
module.exports = {Task,TaskGroup}

Converting the example code on the task class from js to coffeescript fixed it


[zgui] Added getWantTextInput

Added zguiIoGetWantTextInput into zgui.cpp, and added binding in gui.zig with getWantTextInput.
This should resolve Issue 491

Thanks!


42 ioutil replacement

The ioutil package is now considered to be deprecated.  This PR replaces all found usages of the ioutil package with appropriate calls to the io or os package instead
Issue: https://github.com/MicahParks/keyfunc/issues/42

Looks perfect!


Always given a validated email when accepting an invitation

Assigning to @simong for review. @nicolaasmatthijs feel free to pick it up instead if you get time tonight.

LGTM, couple of small things, back to @mrvisser

Added a test for an external provider not providing an email address when there is and isn't an invitation token.
Google can't be used as an external auth provider that doesn't return an email because the email is the external id so it is required. I didn't use Twitter because it uses OAuth 1.1 which I'm assuming would require signing responses. Facebook seemed like the best choice.

back to @simong for review


ComboBox changes does not trigger on_changed callback

Describe the bug
When the selected item of a ComboBox is changed, the on_changed callback is not called.
To Reproduce
I have made a little example:
use orbtk::prelude::*;

fn main() {
    Application::new()
        .window(|ctx| {
            Window::new()
                .title("Test")
                .position((100.0, 100.0))
                .size(700.0, 500.0)
                .resizeable(true)
                .child(
                    ComboBox::new()
                    .v_align("center")
                    .h_align("center")
                    .on_changed(move |_states, _entity, property| {
                        println!("Changed {}",property);
                    })
                    .items_builder(|bc,index|{
                        match index {
                            0 => TextBlock::new().text("Bottom").build(bc),
                            1 => TextBlock::new().text("Top").build(bc),
                            2 => TextBlock::new().text("Left").build(bc),
                            3 => TextBlock::new().text("Right").build(bc),
                            _ => panic!()
                        }
                    })
                    .count(4)
                    .selected_index(0)
                    .build(ctx)
                )
                .build(ctx)
        })
        .run();
}

This should print "Changed {property name}" every time a property of the ComboBox change, but nothing is printed.
Expected behavior
When a ComboBox property is changed, an on_changed callback should be triggered.
Desktop (please complete the following information):

OS: AML-S905X-CC (Le Potato) AARCH64 Debian Buster upgraded to Sid

Additional context
Seem to be the same problem that happen to NumericBox, maybe have the same root?

fixed

Thanks!


Transaction expiring when materializing a table from a long running query

We have been running into the following errors when using table materialization on Trino queries which ran for a certain period of time (cca over 320 seconds):
failed to commit transaction 8c6a8ab8-6458-47dc-956f-8195c33e8cc1: PrestoUserError(type=USER_ERROR, name=UNKNOWN_TRANSACTION, message="Unknown transaction ID: 8c6a8ab8-6458-47dc-956f-8195c33e8cc1. Possibly expired? Commands ignored until end of transaction block", query_id=20210811_123350_12052_t27c7)
The problematic part is the following 'main' statement block in the materialization macro:
https://github.com/dbt-labs/dbt-presto/blob/a32f92e664f34ab61d77dc8790123e5c2e6b466d/dbt/include/presto/macros/materializations/table.sql#L36-L38
As the create statement doesn't need transaction block around it, we've tried to turn it off by customizing the materialization macro by adding the "auto_begin=False" to the main statement block. This doesn't work with dbt, it complains that the transaction is not open. We were able to work around this behaviour by running the create statement before the 'main' statement block and inserting a dummy select into the block but that alters the outputs in "target/run/" folder.
We thought that the issue is related to the used Presto/Trino driver but we've tried running the code also using the dbt-trino package with trino-python-client but the output error is the same.
What could be the cause of this issue? Can it be fixed from dbt-presto side or is this affecting the dbt-core? Is there a cleaner solution to this problem than the one I described above, possibly allowing the 'main' statement block to run without transaction?

I was having the same issue, and you can work around this by setting this trino setting for transaction timeouts:
transaction.idle-timeout=4h

or however long your queries run. Note that it can only be set in config.properties, not via session property

Is there any specific reason why transactions are explicitly started in dbt-presto even though the python client is using AUTOCOMMIT


Show external URLs

Sorry if I seem a bit daft here, just came across your plugin and it looks neat and small. I just can't get it to work on external URLs - is this possible to do?
In your example files, the AJAX URL is internal.

featherlight uses $.ajax (more precisely $.fn.load), so if that works, featherlight will work.
You have to be careful about the "same origin policy" though. See here for example.


Failed to clone git@github.com:jamisonvalenta/Laravel-4-generators.git, git was not found

I'm getting this error. I should have no typos. Everything is copied directly from the readme.
[RuntimeException]
Failed to clone git@github.com:jamisonvalenta/Laravel-4-generators.git, git was not found, check that it is installed and in your PATH env.
'git' is not recognized as an internal or external command,
operable program or batch file.
"require-dev": {
"fzaninotto/faker": "~1.4",
"mockery/mockery": "0.9.",
"phpunit/phpunit": "~4.0",
"symfony/css-selector": "2.8.|3.0.",
"symfony/dom-crawler": "2.8.|3.0.*",
"xethron/migrations-generator": "dev-l5",
"way/generators": "dev-feature/laravel-five-stable" },
"repositories": {
"repo-name": {
"type": "git",
"url": "git@github.com:jamisonvalenta/Laravel-4-generators.git"
}

same here

any solution ? same problem

The new version does not make use of jamisonvalenta/Laravel-4-generators.git. So you can remove the repository from your composer.json, as well as removing way/generators. And change xethron/migrations-generator to use version "~2.0.1"

Hello unfortunately I have the same error could you tell me how to fix it


Env Viz: Avoid trivial steps

Example:

Step 2 has no change compared to Step 1. It should be avoided.
Step 3 has only a semicolon removed, compared to the previous step. We should avoid such a trivial step.

This issue seems to be solved already. @dickongwd @vansh284 can you check and close the issue?

Closed by https://github.com/source-academy/js-slang/pull/1436


Remote Desktop Idea, Improvement?

Hej,
i'm currently working a lot with ffmpeg at Work writing basically a Desktop Stream Software something like Teamviewer without control.
It's really amazing what you can do with ffmpeg (30-60fps x1080p). So I was thinking and want to know from @MaxXor would this be something you might want? :)

@ValonK possible to get 4bit and 1bit streams with ffmpeg?

Yeah its possible ! ffmpeg is very powerful its been developed by so many people. https://ffmpeg.org/

@ValonK Out of curiosity, would this be applicable to webcam streaming as well?  I'm not sure why the current implementation of that seems so slow/bandwidth intensive when programs like skype seem to be able to handle it fine (and even meterpreter's method seems to give higher fps video with better quality)
Either way, improving the desktop streaming would be a really nice improvement!  Especially if you could set some parameters on it.

Among other things the current implementation of remote desktop is passed on PULL model instead of traditional PUSH based model which actually results in low performance because the server requests the next frame. See https://github.com/quasar/QuasarRAT/issues/502

@Cowboy-Curtis with FFmpeg you can stream everything that is streamable ;) I will start with a prototype and show some of the capabilities of FFmpeg. The only problem is that the ffmpeg.exe needs to be on the victims Pc. So basically if the stream gets started we first need to upload ffmpeg.exe ~40.mb, but believe me its worth it!!! As an example I streamed a whole movie from my work PC  to my Home PC without an issue!!

@Cowboy-Curtis with FFmpeg you can stream everything that is streamable ;) I will start with a prototype and show some of the capabilities of FFmpeg. The only problem is that the ffmpeg.exe needs to be on the victims Pc. So basically if the stream gets started we first need to upload ffmpeg.exe ~40.mb, but believe me its worth it!!! As an example I streamed a whole movie from my work PC  to my Home PC without an issue!!

We can keep the current implementation and add the FFmpeg method along side with it but we need to try to find a lite version of FFmpeg to decrease the size

We can keep the current implementation and add the FFmpeg method along side with it but we need to try to find a lite version of FFmpeg to decrease the size

I will see if I can find some lite version.

I will see if I can find some lite version.

@ValonK can you give us a proof of concept? I am very interested in this idea, I need faster remote desktop sessions

Hej,
I'm working on it. it takes time and it is a lot of work. I did find a video with Linux but it's the same with windows. When I have a working build I will post it here. https://www.youtube.com/watch?v=SDU0vb5KVqo

Work is in progress guys http://imgur.com/a/5sPzl :)

@ValonK i would be very happy to see this!
I also started working on a small codec....involving few techniques...stuck somewhere...haha

@ValonK thank you sir! can you provide us with 4bit and 1bit lossless compression?

@ValonK sir, I can help you with something? Got some free time and want to learn

@ValonK any progress this days?

@chico-depressive there isn't much left , we have a deadline currently at Work. I will try to complete it this Weekend.

@ValonK sir, if you need any help please tell me
how did you get this knowledge? you read a lot of books?

Thanks @chico-depressive
Yeah I went to university and now I'm working as a dev :)
You can help me with Testing because I'm not using Quasar and I don't have any Machines that i "control", so testing this is not possible for me when I complete the Feature you could Test and Report any bugs or improvements to me.

@ValonK consider it tested :)

@ValonK @chico-depressive  the main boost will come from devleoping a smart scanning algorithm which can easily detect changed regions...fast and accurate..i'm working on somthing like that..
we can work on it together if you want guys...

@chico-depressive it all depends on internet connection on both sides , the Connection is the most important thing!
@itapi Sure sound very interesting, we can when this feature is finished

Im glad to know youre still around and working on this, and I don't mean to sound like a beggar, but do you have any ETA on when this might be finished?  It's something I'm really looking forward to!

@Cowboy-Curtis @ValonK me too, any help you need to speed it up, just tell me

Ok guys yeah, here's my discord so we can talk tomorrow and you can help me..
iNCEPTiON#8725 :)

@ValonK great! but invite expired for this link

Sorry I'm new in discord I will give you new one when I'm home or you give us yours

@ValonK hi, do you have skype or some kind of contact? thinking about donating to speed up the project, do you accept bitcoin?

@ValonK Are you still working on this? i have some free time and some knowledge regarding ffmpeg
Send us a discord link when you have some time :)

@knackrack615  @chico-depressive  i'm working on self implemented codec ,using libjpgTurbo library,and many other improvments.
your welcome help.
my skype name is Itamar.Yehezkel2

great guyz, let's make remote desktop as fast as possible, challenge accepted, lol

@itapi I do not know if you know, but google released recently a new libjpg with better compresion rates just forgot the name

we can all talk on IRC, maybe create a channel for quasar 💃💃💃💃💃💃💃💃 💯 🥇🥇🥇🥇🥇🥇🥇

anyone using jabber?

An IRC channel would be cool.

@chico-depressive  this is the guetzli  extremly slow.. not for use right now

Note: Guetzli uses a large amount of memory. You should provide 300MB of memory per 1MPix of the input image.
Note: Guetzli uses a significant amount of CPU time. You should count on using about 1 minute of CPU per 1 MPix of input image.
O.O

@itapi "libjpeg-turbo is a JPEG image codec that uses SIMD instructions (MMX, SSE2, AVX2, NEON, AltiVec) to accelerate baseline JPEG compression and decompression on x86, x86-64, ARM, and PowerPC systems."
cool!

Alright everyone, i've made a Discord server for Quasar where we can all talk
https://discord.gg/4vSJ372
(You don't need a discord account to join but it would be a good idea to make one)

Kinda curious what happened with this, it seemed like so many people were interested in it but checking up on things it looks like nothing solid has gotten done yet :(  Quasar rat with @ValonK 's audio recording is pretty much perfect except for it's current remote desktop/webcam streaming.  I've tried a lot of other software out there right now and they all have problems that make them nonviable.
I know everyone is busy with their own lives though, and I will continue to look forward to whatever the people the people working on this come up with!  I will help with whatever I can but lack coding knowledge/experience but always like learning.

@Cowboy-Curtis From observation it seems that this project is at an indefinite standstill until MaxXor is out of college and has time to devote or this becomes a commercial (paid) project.
Unfortunate, but most big projects eventually run into this wall. 😢

I have much work going on private but... this remote desktop stream is not dead. This should be experimental since it requires lot of bandwith on both sides. I will continue this.
The north never forgets. ;)

Glad to hear people out there still care!  I actually spent some time learning about ffmpeg which was interesting and it's fairly easy to just dump it on a remote machine with a batch file that streams desktop/webcam back to you.  Much better than what's currently in quasarrat since I don't care about bandwidth and an option people might want to learn who aren't tech savvy enough to help code something into this rat.

Fffmpeg is powerful. This is how I'm trying to build this into Quasar:

Check if User has Vlc or FFmpeg.
If so Choose Options in Quasar GUI.
The FFmpeg Command should look something like  https://pastebin.com/jxkpaYFM
Send Command to User and Start Hidden FFmpeg or VLC Process.
Start Admin Window in Quasar or VLC to watch the Stream.

Potential Problems:
High Bandwith on both Sides
High Ram or CPU on User Machine, potential detection


Push to Dockerhub

Would it be possible to push this on Dockerhub,
it doesn't has to be the official geminabox image,
just having the possibility of pulling it without building it first.
Thank you and
with best regards

I just did it. Try it now if you want.

Awesome!
What dockerhub user + repo is used?
I tried to find it by the github repo name, but it doesn't seem to have the same name.
It may be helpful to add the docker pull command to the README.

Thank you @strarsis for your suggestion. I just added the image repo URL.

It may be necessary that you have to push the first image.
$ docker pull jaml/jewellery.rb
Using default tag: latest
Pulling repository docker.io/jaml/jewellery.rb
Tag latest not found in repository docker.io/jaml/jewellery.rb


[front] - enh(assistant-builder): vaults empty

Description
This PR aims at handling more nicely the data selection step within the assistant builder. When a managed data source is empty we display a button to enable the addition/request of data directly within the modal.
References:

https://github.com/dust-tt/tasks/issues/1340

Risk
Low
Deploy Plan
Deploy front

Note: most files are edited to be able to pass params around..


Job workloads

Description
Changes proposed in this pull request:

add job list and details
create a common ResourcePods component for pod lists
important use the ResourcePods for replica sets - not 100% sure if the results are correct, as the original fetched everything and filtered manually (but since replica sets have all the necessary references, and I didn't notice any differences, I assume it's correct)

Awesome work dude!

I've approved this and added the don't-merge label - what do you think about adding a reference to parent on Job's details view? We could take it's ownerReference and point to Function (building jobs), to CronJob or don't show this column at all (for example Job hb-gcp-se-defaul-39fd4ba1-46e4-4415-b2ae-22290e71d533-gcp-servi in default namespace on kmain cluster doesn't have an owner ref).
If you don't think it's worth it, just remove my label.


Security Vunerability - Update svgo

The version of svgo in this project has a vunerability in it's js-yaml dependencies. This has been resolved in svgo 3.13.0+. Please update the svgo dependency verion.

Hi @simeon-smith!
Thanks, I updated svgo to the latest version in the latest release.


Feature: A way to run the Action as a local service

Package managers (e.g., npm) need to implement sigstore client library to enable provenance for their users. If we could turn the GHA in this repo into a deamon (that users could can add as a step), it would lower the barrier to entry. Package managers could send a REST API to a local address and get the provenance in the response.
Maybe there's another way to do it, but above is the first that comes to mind

TBH I'm not 100% what you're asking for here - do you mind clarifying?  The Action writes provenance, and GH CLI verifies it. I don't follow turn the GHA in this repo into a daemon (that users could add as a step)
The new gh-attestation CLI extension / command ships the trust root for both GitHub and Sigstore PGI Fulcio instances, so anything constructed on GitHub can be subsequently verified in a fairly high-trust way b/cgh is a static binary. You could imagine package managers potentially shipping this binary to client machines in the future.
To my way of thinking, the larger barrier to entry for registry adoption is getting registries to produce a publish attestation (the way that npm does today) in order to bind the published artifact to the build job that produced it.

Let me clarify. As a package manager CLI, if you want to start sending provenance to my registry, you have 2 options:

Implement a Sigstore client in the language the CLI is written with. For npm, that was sigstore-js
Use a platform-provided feature

(1) is a lot of work and a barrier to entry. (2) is seems a better option. A package CLI cannot use call a GitHub Action. So there are 2 options for a CLI to take advantage of this Action:

Ask users to split the npm publish (or equivalent for their package manager) into 2 step: cli create-package, then call the Action in this repo, then call cli publish-tarball.
Let users call the GHA to set up a deamon that listens on a local port on the runner. The CLI then just needs to implement a REST API call to <IP_ADDRESS>:port.

(1) does not seem great UX-wise, and may be complicated for certain ecosystems that create multiple files (Maven?).
So I was suggesting option (2). A GitHub Action (or this one with a specific --as-daemon option) that would listen to a local port and sign artifact on demand. Users would add a step to their job before calling cli publish --with-provenance


FFDC failing with several failures in automation code.

Several failures occurred:

EOFError
SSHException: SSH session not active
Could not get length of 'None'.
Could not get length of 'None'.

This is a good bug if we can resolve it.. @micwalsh is coming up new mechanism to re use the sessions.. once that's in place this would be history for most of the error..


Connector cannot restart after closed

Describe the bug
We want to implement a dynamic configuration system in which after updating the config, the connector needs to be closed and started again. But we're getting "duplicate metrics collector registration attempted" error when the second connector is registering its prometheus metric connector.
To Reproduce
Create a connector, start it, close it.
Then create a new connector and start it.
Expected behavior
While closing the connector, it should unregister all prometheus collectors which causes the duplicate error.
Stack Trace

Stack Trace:

hi @EmreKumas sorry to hear that and thank you for your contribution.
we will publish a fix 👍

Thank you for your support, we’re waiting this fix 🙏 btw we tried to unregister  all prometheus collectors but after that we faced fiber prometheus metric problem also fyi.

Hello @firatferoglu we've implemented a fix but I got confused about what you guys tried. how did you try to unregister collectors? is that similar to what we did below?
https://github.com/Trendyol/go-dcp/pull/61/files

Yes, it looks similar. We edited the code in the vendor folder and unregistered prometheus collectors.
I also try this branch locally but, same error still exists :(
I changed unregisterMetricCollectors() method as below.
`
func (s *dcp) unregisterMetricCollectors() {
for i := range s.metricCollectors {
result := prometheus.DefaultRegisterer.Unregister(s.metricCollectors[i])
fmt.Println(result)
}
s.metricCollectors = []prometheus.Collector{}

}
`
And observed that the metric is created in api.NewMetricCollector() method couldn't be unregistered.

Thank you for the information. We should investigate the library and find a proper solution. I will update here if I find the reason and solution.

Hello @firatferoglu we have released a new version v1.0.3. Thanks for help 🙏


wow, is this Repo the one you mentioned before?

Hi Thomas!
Is this repo the realitykit inspired AR framework with filament as its rendering core which you mentioned before?
Excited!

Maybe ;-)

Hi @issacclee,
Actually there is only about 10% of the already done work pushed to the repo.
I tried to follow the IO and participate as much as I can on the AMA.
Unfortunately the only answer to more than 50% of the questions : "Where is Sceneform ?" was "You don't need Sceneform, just do the same with OpenGL".
Not even a single world about the work done by the community to maintain it or about the possible Filament usage with ARCore.
Anyway, even if we are only 2 of us using this new SDK, I'll push the rest of the code in coming days because I know all the capabilities an ARCore/Filament framework can bring.
Thanks for your support.

Hi @ThomasGorisse ,
As always, I greatly appreciate your work and I'm sure many developers around the world who benefited from your work on keeping up the Sceneform fork feel so as well.
Recently I've being communicate with a lot of enterprise customers from Asia(China mostly). They all agree in principle that they would like to integrate basic 3d/ar interaction in their product(e-commerce app etc), but they are reluctant to package something like Unity(UAAL) into their existing app code base. While on the apple side they are happy to use realitykit to make such experience happen, however android devices makes up about 80% of market share. So there's definitely a need for project like this to exist, even though it's relatively niche at the moment.

BTW, I'll spread the word around Chinese developer community and maybe do some document translation when you've finish the initial commits of the code that you intended to.

I hope this repo will be useful.
I have discovered so much enjoying things I wouldn't expect doing it that it would be a shame not to share it.
Like the idea of considering the real world returned by the Depth API as a simple Filament 3D shape with UVs in the Scene.
I went from "That's a crazy concept, it will never be reliable but let's try it" to "OMG, that's actually working well, I can now place objects behind my sofa!!!"
Or great discussions with the Filament team about using the returned Environment Lighting as a Skybox (you can see what it will looks like here :  https://github.com/google/filament/discussions/3607
Unity is great and can do a lot of things. But, as you mentioned, a lot of clients just want to only integrate AR in their actual App. Unity is not lite to integrate and cannot really interact with the rest of the app and the Model viewer Intent is the not enough.
In my point of View Unity is just like Flash at its beginning. Great and beautiful but when comes the time to know "What can be the concrete usage?", I think, just like for Flash, that's the answer will be "Mostly Games" since it's not completely integrated in the Android app ecosystem.
All that to say thanks a lot for bringing back the desire to finish pushing after the ARCore declarations.

"Where is Sceneform ?" was "You don't need Sceneform, just do the same with OpenGL".

I was happy they addressed my question during I/O but I was also disappointed with the response. I'm so glad that you are working on this implementation. I am a noob developer, trying my hardest to keep up, but I am happy to help in any way I can. I will surely have questions as this project matures. Thanks for your work on this, @ThomasGorisse!

Hi, @ThomasGorisse!
Do you still need help with the materials?

Hi @grassydragon,
Yep, more than ever.
Actually, I don't completely know if we should do the things in Sceneform or RealityCore.
I spend a lot of time making corrections and evolutions on Sceneform and I let RealityCore a little bit down this days.
I really think this repo could be awesome and a great move for AR on Android but there is so much need of users on Sceneform that I don't know where to go.
I was actually at the point of moving Sceneform material classes to Kotlin.
What do you guys think?
@rgregrat, would you also like to participate here?

I was actually at the point of moving Sceneform material classes to Kotlin.

Do you mean in Sceneform or moving them here?

In Sceneform.
Cause there are actually 4 classes with an enormous count of boilerplate/unused code wich could be cleaned in 50 lines of code thanks to Kotlin extensions.

@ThomasGorisse
Count me in, but except for a few Udemy courses I never programmed in Kotlin. My product codebase is completly written in java and as a solo developer I have currently no time to migrate.
On the other hand, is this repo a good opportunity to get used to Kotlin :)

@RGregat

Count me in, but except for a few Udemy courses I never programmed in Kotlin.

Thanks!!!! You already do a very good job on Sceneform, it will be cool to have you in here.

My product codebase is completly written in java and as a solo developer I have currently no time to migrate.

In a way, I envy you for not knowing the wonderful world of Kotlin yet.

On the other hand, is this repo a good opportunity to get used to Kotlin :)

I also think so and I will guide you within the PR for making things more clean and Kotlin certified for you.

And I like the ECS idea. I used something ECSish for a frontend map view and I was very pleased with the result.

I was first a little bit doubtful when I saw the ECS.
Like "OK, here comes some new conceptual think made for people who wants to spend hours making code worst at the end".
But it is completely made for case like in AR where many calculations are made at a same time by different actors.
Quick example:

In Sceneform, you have to load your model with a CompletableFuture then load your materials in another CompletableFuture then load your textures then apply it to each other and wait for that to be ready before being able to add your node to the Scene when a user tap on a plane which is also part of another calculation made by ARCore.

In an Kotlin ECS context that will mostly be:

val modelEntity = loadGlb("model.gmb")) //You have access to the model even if the gltf is not completely loaded yet
modelEntity.material["wheels"] = loadMaterial("material.filamat") //Behind it only the entity id is passed to Filament so it can handle the fact that the model isn't completely loaded yet and wait for only the loaded parts of the model it needs to apply material
model.material["wheels"].externalTexture = loadTexture("texture.png") //Same thing, even if the material is not completely loaded we can tell Filament to apply the texture to the material entity id when things are ready for it.
scene.addEntity(model) //The entity is added and will be rendered progressively
model.position = Position(0.0,1.0,0)

The only things that must be done or not (that's a subject I'm thinking about this times) in a worker thread (not in the UI one) is the file InputStream to Buffer.
Comparing to Sceneform case, if any component (Renderable, Material, Texture, Anchoring) takes a long time to load there will have no impact on over calls and we can use not already loaded things since there are just passed to Filament as an Entity Id (= an int)

That sounds indeed really good. Of course I have a few things I would like to see in realitycore:

ViewRenderable
PointCloudRenderable
StrokeRenderable
In general some primitve types like cube, sphere, polygon, plane
Drag & Drop
World position of a Node (with world I mean the local coordinate of an attached anchor)
Scaling and rotation of Nodes
A few predefined materials with the ability to modify the color and other attributes.
Set what is visible and what not, like an enable disable toggle.
Access to the camera (position, rotation)
Selection of renderables

:)

I implemented point cloud rendering in my project using spheres with a transparent unlit material. I add and remove the Filament entities from the scene dynamically and reuse the previously created entities.

Wow. So much infos at the same time !!!

@RGregat Thanks for the list
It's good to have a result scope in mind when implementing what they are made of.
Mostly everything seems to be realistic.
For the high level usage part (StrokeRenderable, predefined materials,...), @SimonMarquis is doing an awesome work here : AR-Toolbox, which made me definitely think that we can do mostly everything that Unity can from an ARCore-Android/Filament SDK when I start maintaining Sceneform.
And which could be included or linked to this repo for simplifying/demonstrating capabilities.

BTW @SimonMarquis, if you see this comment, why not moving your dependency to Sceneform SDK for Android - Maintained?
If you need help for migrating, we are here.

@grassydragon You mean without using Sceneform?

@ThomasGorisse ;-) Your way to implement the Filament extensions in a Coroutine context looks good
Material.kt

suspend fun AssetManager.loadMaterial(
    fileName: String,
    apply: Material.Builder.() -> Unit = {}
): Material = loadAsset(fileName, create = { buffer ->
    Material.Builder().payload(buffer, buffer.remaining())
        .apply(apply)
        .build(filamentEngine)
}, destroy = { it?.destroy() })

fun Material.destroy() {
    filamentEngine.destroyMaterial(this)
}

Io.kt
suspend fun <R> AssetManager.loadAsset(filename: String, create: suspend (ByteBuffer) -> R, destroy: ((R?) -> Unit)?): R = withContext(Dispatchers.IO) {
    val asset: R? =null
    try {
        open(filename).use { inputStream ->
            val bytes = ByteArray(inputStream.available())
            inputStream.read(bytes)
            val byteBuffer = ByteBuffer.wrap(bytes)
            withContext(Dispatchers.Main) {
                create(byteBuffer)
            }
        }
    } finally {
        destroy?.invoke(asset)
    }
}

and linking all the Filament loaders to the view lifecycle scope like this is a good idea since it will remove the ARFragment needing
ARView.kt
val lifecycleScope: Flow<LifecycleCoroutineScope> = callbackFlow {
    val listener = object : OnAttachStateChangeListener {
        override fun onViewAttachedToWindow(v: View?) {
            removeOnAttachStateChangeListener(this)
            offer(findViewTreeLifecycleOwner()!!.lifecycleScope)
        }

        override fun onViewDetachedFromWindow(v: View?) {
        }
    }
    addOnAttachStateChangeListener(listener)
    awaitClose { removeOnAttachStateChangeListener(listener) }
}

init {
    if (!context.isOpenGlVersionSupported(Filament.MIN_OPENGL_VERSION)) {
        throw OpenGLVersionNotSupported
    }
    MainScope().launch {
        lifecycleScope.collect { lifecycleScope ->
            lifecycleScope.launchWhenResumed {
                try {
                    session.resume()
                    renderer.start()

                    awaitCancellation()
                } finally {
                    renderer.destroy()
                    session.pause()
                }
            }
        }
    }
}

but what do you guys think about it because it's a great idea to push it soon ?

Note :
fun View.findViewTreeLifecycleOwner() from androidx.lifecycle is a great add for managing all from the ARView instead of an ARFragment and as an SDK user that can be really great to just have to add the ARView to the layout
Throwing exception if OpenGL version is too low since it's a manifest requirement but not for the ARCore compatibility = Simple 3D view if no ARCore.
How to handle the same usage without hit test or augmented image or augmented face (AugmentedFaceNode PR will be merged soon to Sceneform) is another question that should, maybe, be handled by the user.

@grassydragon You mean without using Sceneform?

Yes, the code only depends on ARCore and Filament but still Sceneform is used in the project for the AR initialization and ViewRenderables.

@RGregat and @grassydragon I added you to the sponsors-enabled usernames.
If you enable sponsoring on your account you will be linked to this repo and the Sceneform one.

In fact, you need to create your sponsor account (If you want so) before I can add you


Updated regexes to remove errors add features

After repeatedly seeing -denyURL q{([ /=]|\t|\n)(ls|rm|cat)([ ;'"&].*)?$} in profiles (https://support.citrix.com/article/CTX225982), I added the q{}  and q// syntax. I also included space characters to ensure that this doesn't happen in the middle of another string.
Initial verbs nailed to the start of a line.
Added UIInternal entity type syntax elements (https://developer-docs.citrix.com/projects/netscaler-command-reference/en/12.0/basic/uiinternal/uiinternal/).
Added more ns config elements.
Added highlighting of (some) bad ciphers - Note that this only looks for the most obvious cipher suite issues, such as MD5 hashing, use of DES/3DES and use of SSLv2 and SSLv3.

HTH - This extension is super-useful! Happy to discuss.

Added more language elements and reorganised.

I can see you've been busy! I'll have a look at evaluating these in the next few days. I had been focussing on refactoring the language grammars to make things easier to maintain, as well as trying to fix the inconsistencies in integer highlighting. I'll move my changes to a later release and look to focus on yours for the next release.
Thanks.

Looks great, really appreciate your contribution. I've released your changes a v0.3.0.