fyflow-orchestration 0.7.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,5 @@
1
1
  import {
2
+ ASK_REFUSED_KEYS,
2
3
  BUILT_IN_GATE_TYPES,
3
4
  BUILT_IN_GROUP_TYPES,
4
5
  BUILT_IN_NODE_TYPES,
@@ -21,6 +22,7 @@ import {
21
22
  InvalidRunId,
22
23
  InvalidTaskId,
23
24
  KEY_PATH_RE,
25
+ MESSAGE_OPTION_KEYS,
24
26
  MissingJoinPolicy,
25
27
  MultipleRuns,
26
28
  NODE_KEYS_DECLARED,
@@ -30,6 +32,7 @@ import {
30
32
  NoMatchingEdge,
31
33
  NotStarted,
32
34
  POLICIES,
35
+ POOL_INSTANCE_KEYS,
33
36
  POOL_SPEC_KEYS,
34
37
  PREDICATE_GROUP_KEYS,
35
38
  PREDICATE_LEAF_KEYS,
@@ -41,10 +44,12 @@ import {
41
44
  RETRY_POLICY_KEYS,
42
45
  RegistryError,
43
46
  ResumeRefused,
47
+ RunControlRefused,
44
48
  SCHEMA_KEYWORDS,
45
49
  SCHEMA_TYPES,
46
50
  SchemaRefused,
47
51
  TASK_KEYS_DECLARED,
52
+ TERMINAL_EVENTS,
48
53
  TRANSFORM_KEYS,
49
54
  TypeDefaultRefused,
50
55
  UncloneableResult,
@@ -90,11 +95,14 @@ import {
90
95
  gateTypeCollisions,
91
96
  gateTypeProblem,
92
97
  gateTypesOf,
98
+ givenVerdict,
93
99
  groupsNamedBy,
100
+ innermostMapOf,
94
101
  innermostRegionOf,
95
102
  isDerivation,
96
103
  isSuspended,
97
104
  isTerminal,
105
+ isTerminalEvent,
98
106
  keyPathProblem,
99
107
  languagesOf,
100
108
  lastRecordFor,
@@ -122,6 +130,7 @@ import {
122
130
  resolveRegistry,
123
131
  resumeRefusal,
124
132
  retryPolicyProblem,
133
+ routesOf,
125
134
  sampleOf,
126
135
  schemaProblem,
127
136
  selectEdge,
@@ -134,7 +143,7 @@ import {
134
143
  violatedRules,
135
144
  witness,
136
145
  workersOf
137
- } from "./chunks/chunk-YVOP3DIN.js";
146
+ } from "./chunks/chunk-EUU44PHD.js";
138
147
 
139
148
  // src/definition/assist.ts
140
149
  var TYPES = ["object", "array", "string", "number", "integer", "boolean", "null"];
@@ -174,8 +183,8 @@ async function tryTransform(registry, flow, nodeId, transform, options = {}) {
174
183
  else copy.transform = { lang: transform.lang, expr: transform.expr };
175
184
  return copy;
176
185
  });
177
- const report = await checkWiring(registry, { ...flow, nodes }, options);
178
- return report.verdicts.filter((v) => v.consumer === nodeId);
186
+ const { input, ...wiring } = options;
187
+ return await givenVerdict(registry, { ...flow, nodes }, nodeId, input, wiring);
179
188
  }
180
189
  function schemaOfValue(v) {
181
190
  if (v === void 0) return void 0;
@@ -278,13 +287,8 @@ function signaturesOf(workers) {
278
287
  }
279
288
  var PATH_TYPES = ["*", ...TYPES];
280
289
  var TS_TYPE_NAMES = [...TS_STRUCTURED, ...TS_NAMES.keys()];
281
-
282
- // src/driver/events.ts
283
- var TERMINAL_EVENTS = ["branch.arrived", "branch.exited", "branch.lost"];
284
- function isTerminalEvent(e) {
285
- return TERMINAL_EVENTS.includes(e.type);
286
- }
287
290
  export {
291
+ ASK_REFUSED_KEYS,
288
292
  BUILT_IN_GATE_TYPES,
289
293
  BUILT_IN_GROUP_TYPES,
290
294
  BUILT_IN_NODE_TYPES,
@@ -307,6 +311,7 @@ export {
307
311
  InvalidRunId,
308
312
  InvalidTaskId,
309
313
  KEY_PATH_RE,
314
+ MESSAGE_OPTION_KEYS,
310
315
  MissingJoinPolicy,
311
316
  MultipleRuns,
312
317
  NODE_KEYS_DECLARED,
@@ -317,6 +322,7 @@ export {
317
322
  NotStarted,
318
323
  PATH_TYPES,
319
324
  POLICIES,
325
+ POOL_INSTANCE_KEYS,
320
326
  POOL_SPEC_KEYS,
321
327
  PREDICATE_GROUP_KEYS,
322
328
  PREDICATE_LEAF_KEYS,
@@ -328,6 +334,7 @@ export {
328
334
  RETRY_POLICY_KEYS,
329
335
  RegistryError,
330
336
  ResumeRefused,
337
+ RunControlRefused,
331
338
  SCHEMA_KEYWORDS,
332
339
  SCHEMA_TYPES,
333
340
  SchemaRefused,
@@ -380,7 +387,9 @@ export {
380
387
  gateTypeCollisions,
381
388
  gateTypeProblem,
382
389
  gateTypesOf,
390
+ givenVerdict,
383
391
  groupsNamedBy,
392
+ innermostMapOf,
384
393
  innermostRegionOf,
385
394
  isDerivation,
386
395
  isSuspended,
@@ -414,6 +423,7 @@ export {
414
423
  resolveRegistry,
415
424
  resumeRefusal,
416
425
  retryPolicyProblem,
426
+ routesOf,
417
427
  sampleOf,
418
428
  sampledOutput,
419
429
  schemaOfValue,
@@ -2,6 +2,7 @@ import {
2
2
  BUILT_IN_NODE_TYPES,
3
3
  ConfigRefused,
4
4
  Driver,
5
+ InvalidDefinition,
5
6
  InvalidTaskId,
6
7
  TypeDefaultRefused,
7
8
  checkGateTypes,
@@ -20,38 +21,23 @@ import {
20
21
  poolsOf,
21
22
  resolveRegistry,
22
23
  resumeRefusal,
24
+ retryPolicyProblem,
23
25
  step,
26
+ validateDefinition,
24
27
  workersOf
25
- } from "../chunks/chunk-YVOP3DIN.js";
28
+ } from "../chunks/chunk-EUU44PHD.js";
26
29
 
27
30
  // src/scheduler/bootstrap.ts
28
31
  import { WorkerManager } from "fyflow-scheduler";
29
32
 
30
33
  // fyflow-envelope-worker:envelope-worker
31
- var envelope_worker_default = "data:text/javascript;base64,Ly8gc3JjL3NjaGVkdWxlci9lbnZlbG9wZS13b3JrZXIudHMKdmFyIE5vdEFuRW52ZWxvcGUgPSBjbGFzcyBleHRlbmRzIEVycm9yIHsKfTsKdmFyIFRyYW5zZm9ybUZhaWxlZCA9IGNsYXNzIGV4dGVuZHMgRXJyb3IgewogIGxhbmc7CiAgZXhwcjsKICBjb2RlOwogIGNvbnN0cnVjdG9yKHRyYW5zZm9ybSwgY29kZSwgd2h5KSB7CiAgICBzdXBlcihgdHJhbnNmb3JtIGZhaWxlZCBcdTIwMTQgJHt0cmFuc2Zvcm0ubGFuZ30gJHtKU09OLnN0cmluZ2lmeSh0cmFuc2Zvcm0uZXhwcil9JHtjb2RlICE9PSB2b2lkIDAgPyBgIFske2NvZGV9XWAgOiAiIn06ICR7d2h5fWApOwogICAgdGhpcy5sYW5nID0gdHJhbnNmb3JtLmxhbmc7CiAgICB0aGlzLmV4cHIgPSB0cmFuc2Zvcm0uZXhwcjsKICAgIHRoaXMuY29kZSA9IGNvZGU7CiAgfQp9OwpmdW5jdGlvbiB1bnBhY2tFbnZlbG9wZShwYXlsb2FkKSB7CiAgaWYgKHR5cGVvZiBwYXlsb2FkICE9PSAib2JqZWN0IiB8fCBwYXlsb2FkID09PSBudWxsIHx8IEFycmF5LmlzQXJyYXkocGF5bG9hZCkpIHsKICAgIHRocm93IG5ldyBOb3RBbkVudmVsb3BlKGB0eXBlZCBwb29sOiB0aGUgcGF5bG9hZCBpcyBub3QgYW4gZW52ZWxvcGUgeyBzZXR0aW5ncywgaW5wdXQgfSBcdTIwMTQgZ290ICR7YnJpZWYocGF5bG9hZCl9YCk7CiAgfQogIGNvbnN0IHAgPSBwYXlsb2FkOwogIGZvciAoY29uc3QgayBvZiBbInNldHRpbmdzIiwgImlucHV0Il0pIHsKICAgIGlmICghKGsgaW4gcCkpIHRocm93IG5ldyBOb3RBbkVudmVsb3BlKGB0eXBlZCBwb29sOiB0aGUgcGF5bG9hZCBpcyBub3QgYW4gZW52ZWxvcGUgXHUyMDE0IGl0IGhhcyBubyAiJHtrfSIga2V5IChrZXlzOiAke09iamVjdC5rZXlzKHApLm1hcCgoeCkgPT4gYCIke3h9ImApLmpvaW4oIiwgIikgfHwgIm5vbmUifSlgKTsKICB9CiAgY29uc3Qgc2V0dGluZ3MgPSBwLnNldHRpbmdzOwogIGlmICh0eXBlb2Ygc2V0dGluZ3MgIT09ICJvYmplY3QiIHx8IHNldHRpbmdzID09PSBudWxsIHx8IEFycmF5LmlzQXJyYXkoc2V0dGluZ3MpKSB7CiAgICB0aHJvdyBuZXcgTm90QW5FbnZlbG9wZShgdHlwZWQgcG9vbDogdGhlIGVudmVsb3BlJ3Mgc2V0dGluZ3MgaXMgbm90IGEgcGxhaW4gb2JqZWN0IFx1MjAxNCBnb3QgJHticmllZihzZXR0aW5ncyl9YCk7CiAgfQogIGNvbnN0IGVudiA9IHsgc2V0dGluZ3MsIGlucHV0OiBwLmlucHV0IH07CiAgaWYgKCJ0cmFuc2Zvcm0iIGluIHApIHsKICAgIGNvbnN0IHQgPSBwLnRyYW5zZm9ybTsKICAgIGNvbnN0IHdlbGxGb3JtZWQgPSB0eXBlb2YgdCA9PT0gIm9iamVjdCIgJiYgdCAhPT0gbnVsbCAmJiAhQXJyYXkuaXNBcnJheSh0KSAmJiB0eXBlb2YgdC5sYW5nID09PSAic3RyaW5nIiAmJiB0eXBlb2YgdC5leHByID09PSAic3RyaW5nIiAmJiBPYmplY3Qua2V5cyh0KS5sZW5ndGggPT09IDI7CiAgICBpZiAoIXdlbGxGb3JtZWQpIHRocm93IG5ldyBOb3RBbkVudmVsb3BlKGB0eXBlZCBwb29sOiB0aGUgZW52ZWxvcGUncyB0cmFuc2Zvcm0gaXMgbm90IHsgbGFuZywgZXhwciB9IFx1MjAxNCBnb3QgJHticmllZihwLnRyYW5zZm9ybSl9YCk7CiAgICBlbnYudHJhbnNmb3JtID0geyBsYW5nOiB0LmxhbmcsIGV4cHI6IHQuZXhwciB9OwogIH0KICByZXR1cm4gZW52Owp9CmZ1bmN0aW9uIGJyaWVmKHYpIHsKICBjb25zdCBzID0gcHJpbnRhYmxlKHYpOwogIHJldHVybiBzLmxlbmd0aCA+IDEyMCA/IGAke3Muc2xpY2UoMCwgMTE3KX0uLi5gIDogczsKfQpmdW5jdGlvbiBwcmludGFibGUodikgewogIHRyeSB7CiAgICBjb25zdCBqID0gSlNPTi5zdHJpbmdpZnkodik7CiAgICBpZiAoaiAhPT0gdm9pZCAwKSByZXR1cm4gajsKICB9IGNhdGNoIHsKICB9CiAgdHJ5IHsKICAgIHJldHVybiBTdHJpbmcodik7CiAgfSBjYXRjaCB7CiAgICByZXR1cm4gYGFuIHVucHJpbnRhYmxlICR7dHlwZW9mIHZ9YDsKICB9Cn0KZnVuY3Rpb24gY29kZU9mKGUpIHsKICBjb25zdCBjID0gZT8uY29kZTsKICByZXR1cm4gdHlwZW9mIGMgPT09ICJzdHJpbmciICYmIGMubGVuZ3RoID8gYyA6IHZvaWQgMDsKfQpmdW5jdGlvbiBtZXNzYWdlT2YoZSkgewogIGlmIChlIGluc3RhbmNlb2YgRXJyb3IpIHJldHVybiBlLm1lc3NhZ2U7CiAgdHJ5IHsKICAgIHJldHVybiBTdHJpbmcoZSk7CiAgfSBjYXRjaCB7CiAgICByZXR1cm4gcHJpbnRhYmxlKGUpOwogIH0KfQp2YXIgRW52ZWxvcGVXb3JrZXIgPSBjbGFzcyB7CiAgY2ZnOwogIHdvcmtlckNvbnRleHQ7CiAgaW5uZXIgPSBudWxsOwogIC8qKgogICAqICoqU2V0IGJ5IGBzZXR1cCgpYCB3aGVuIHRoZSBwb29sIGNvbmZpZyBuYW1lcyBubyB3b3JrZXIg4oCUIGEgdHlwZSB0aGF0IG9ubHkgVFJBTlNGT1JNUyoqIChBRFIgMDA3NSkuCiAgICogSXQgaXMgYSBTRVBBUkFURSBmaWVsZCBmcm9tIGBpbm5lciA9PT0gbnVsbGAgb24gcHVycG9zZSwgYW5kIHRoYXQgaXMgdGhlIHdob2xlIG9mIHRoaXMgYXJtJ3MKICAgKiBjb3JyZWN0bmVzczogYGlubmVyYCBpcyBudWxsIGJlZm9yZSBgc2V0dXAoKWAgYW5kIGFmdGVyIGB0ZWFyZG93bigpYCB0b28sIHdoaWNoIGFyZSBMSUZFQ1lDTEUKICAgKiBzdGF0ZXMgYHJ1bigpYCBoYXMgcmVmdXNlZCBieSBuYW1lIHNpbmNlIHYwLjE3LCBzbyByZWFkaW5nIHRoZSBhYnNlbmNlIG9mZiBgaW5uZXJgIHdvdWxkIHR1cm4KICAgKiAqcnVuKCkgYmVmb3JlIHNldHVwKCkqIGludG8gKnJldHVybiB0aGUgaW5wdXQgdW50b3VjaGVkKiDigJQgYSBydW4gdGhhdCBzaWxlbnRseSBoYW5kcyBhIHdvcmtlcidzCiAgICogc3VjY2Vzc29yIHRoZSB3cm9uZyB2YWx1ZSBpbnN0ZWFkIG9mIGZhaWxpbmcgdGhlIHRhc2suIE1lYXN1cmVkIGF0IFcxMDkncyBkZWNsYXJhdGlvbiBzdGVwOiBiZWZvcmUKICAgKiB0aGlzIGl0ZW0gQk9USCBvZiB0aG9zZSBzdGF0ZXMgdGhyZXcsIGFuZCBuZWl0aGVyIHdhcyBhbiBhcm0uCiAgICovCiAgbm9Jbm5lciA9IGZhbHNlOwogIC8qKgogICAqIFRoZSB3b3JrZXIgaGFsZiBvZiBlYWNoIGxhbmd1YWdlIHRoZSBwb29sIGNvbmZpZyBuYW1lcywgbG9hZGVkIGluIGBzZXR1cCgpYCDigJQgb3IgdGhlIHJlYXNvbgogICAqIGl0IGRpZCBub3QgbG9hZCwgUkVNRU1CRVJFRCBzbyB0aGF0IGBydW4oKWAgY2FuIGZhaWwgdGhlIHRhc2sgd2l0aCBpdCAodGhlIG1haW50YWluZXIncyBjYWxsLAogICAqIHNlZSBgc2V0dXAoKWApLgogICAqLwogIGxhbmdzID0gLyogQF9fUFVSRV9fICovIG5ldyBNYXAoKTsKICAvKiogRWFjaCBkaXN0aW5jdCBgKGxhbmcsIGV4cHIpYCBjb21waWxlZCBPTkNFIHBlciB3b3JrZXIgaW5zdGFuY2UsIG5ldmVyIHBlciB0YXNrIOKAlCBQMTcgZGVjaXNpb24gMy4gKi8KICBjb21waWxlZCA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgTWFwKCk7CiAgLyoqCiAgICogKipXaHkgdGhpcyB3b3JrZXIgY291bGQgbm90IHNldCB1cCwgUkVNRU1CRVJFRCDigJQgb3IgYG51bGxgKiog4oCUCiAgICogW1cxNDFdKC4uLy4uL2RvYy93b3JrLWl0ZW1zL3cxNDEtYS13b3JrZXItdGhhdC1jYW5ub3Qtc2V0LXVwLWZhaWxzLWl0cy10YXNrcy1hbmQtdGhlLXJlZ2lzdHJ5LWhhcy1vbmUtc2hhcGUubWQpLAogICAqIFtRMjY2XSguLi8uLi9kb2MvcXVlc3Rpb25zL3EyNjYubWQpLCBQMzEgZGVjaXNpb24gMzogVzYxJ3Mgcm9hZCBmb3IgYSBsYW5ndWFnZSwgdGFrZW4gZm9yIHRoZSB3aG9sZQogICAqIG9mIGBzZXR1cCgpYC4gU2V0IGJ5IGBzZXR1cCgpYCBpbnN0ZWFkIG9mIHRocm93aW5nOyByZWFkIEZJUlNUIGJ5IGBydW4oKWAsIHdoaWNoIGZhaWxzIGV2ZXJ5IHRhc2sKICAgKiB3aXRoIGl0OyBjbGVhcmVkIGJ5IGB0ZWFyZG93bigpYCwgc28gYSB0b3JuLWRvd24gd29ya2VyIGlzIGluIGl0cyBjb25zdHJ1Y3RlZCBzdGF0ZSBhZ2Fpbi4KICAgKi8KICBzZXR1cEZhaWx1cmUgPSBudWxsOwogIC8qKgogICAqIEJvdGggYXJndW1lbnRzIGFyZSBrZXB0LCBhbmQgdGhlIHNlY29uZCBpcyBmb3J3YXJkZWQgdG8gdGhlIGlubmVyIHdvcmtlcjogdGhlIHNjaGVkdWxlciBwYXNzZXMKICAgKiBpdHMgd29ya2VyLWxldmVsIGNvbnRleHQgaGVyZSwgYW5kIGEgd29ya2VyIHRoYXQgb25seSBhY2NlcHRzIGBjb25maWdgIHNpbGVudGx5IGxvc2VzIHRoZQogICAqIGFiaWxpdHkgdG8gc2VsZi10ZXJtaW5hdGUgKHRoZSBzY2hlZHVsZXIncyBvd24gcmVmZXJlbmNlLCDCpzQpLgogICAqLwogIGNvbnN0cnVjdG9yKGNvbmZpZywgd29ya2VyQ29udGV4dCkgewogICAgdGhpcy5jZmcgPSBjb25maWc7CiAgICB0aGlzLndvcmtlckNvbnRleHQgPSB3b3JrZXJDb250ZXh0OwogIH0KICAvKioKICAgKiBMb2FkcyB0aGUgdHlwZSdzIHdvcmtlciBhbmQgcnVucyBJVFMgc2V0dXAg4oCUIGEgbW9kdWxlIHdpdGggbm8gZGVmYXVsdCBjbGFzcyBpcyByZWZ1c2VkIGJ5CiAgICogbmFtZSwgYXMgYXQgdjAuMTcg4oCUIHRoZW4gdGhlIHdvcmtlciBoYWxmIG9mIGV2ZXJ5IGxhbmd1YWdlIHRoZSBwb29sIGNvbmZpZyBuYW1lcywgT05DRSBwZXIKICAgKiB3b3JrZXIgaW5zdGFuY2UgKFAxNyBkZWNpc2lvbiAzKS4KICAgKgogICAqICoqQSBsYW5ndWFnZSBtb2R1bGUgdGhhdCBGQUlMUyBUTyBMT0FEIGRvZXMgbm90IHRocm93IGhlcmU7IHRoZSBmYWlsdXJlIGlzIHJlbWVtYmVyZWQgYW5kCiAgICogZXZlcnkgdGFzayB3aG9zZSB0cmFuc2Zvcm0gbmFtZXMgdGhhdCBsYW5ndWFnZSBmYWlscyBhdCBgcnVuKClgIHdpdGggaXQuKiogTWVhc3VyZWQgYXQgVzYxJ3MKICAgKiBkZWNsYXJhdGlvbiwgYm90aCBydW50aW1lcywgaW5saW5lIGFuZCB0aHJlYWRlZDogYSB3cmFwcGVyIHdob3NlIGBzZXR1cCgpYCB0aHJvd3MgbGVhdmVzIGV2ZXJ5CiAgICogdGFzayBvZiB0aGUgcG9vbCBgcGVuZGluZ2Agd2l0aCBgYXR0ZW1wdHM6IDBgLCB0aGUgcG9vbCByZXN0YXJ0cyBpdHMgd29ya2VyLCBhbmQgdGhlIHNjaGVkdWxlcgogICAqIGVtaXRzIG5vdGhpbmcgYSBkcml2ZXIgY291bGQgdHVybiBpbnRvIGEgcmVjb3JkIOKAlCB0aGUgZmFpbHVyZSBpcyByZXBvcnRlZCBvbiB0aGUgUE9PTCBhcwogICAqIGB3b3JrZXIuc2V0dXAuZmFpbGVkYCBhbmQgYHRhc2sucmVxdWV1ZV9yZXF1aXJlZGAsIGEgd29ya2VyIGVycm9yIGFuZCBub3QgYSB0YXNrJ3MsIHdoaWNoIGlzCiAgICogUDE3IHByZWRpY3Rpb24gMidzIHN0YXRlZCByZXZlcnNhbCBjb25kaXRpb24uIFRoZSBtYWludGFpbmVyIGNob3NlIHRoaXMgcm9hZCBhdCBXNjEncwogICAqIHN0b3AtYW5kLWFzayAoQURSIDAwNTEgcnVsZSA1KTogYSBVUkwgdGhhdCBkb2VzIG5vdCByZXNvbHZlLCBhIG1vZHVsZSB3aXRoIG5vIGRlZmF1bHQgY29tcGlsZQogICAqIGZ1bmN0aW9uLCBvciBhbiBlbXB0eSBVUkwsIGVhY2ggYmVjb21lcyBhIGBUcmFuc2Zvcm1GYWlsZWRgIG5hbWluZyB0aGUgbGFuZ3VhZ2UgYW5kIHRoZSBsb2FkCiAgICogZXJyb3IsIG9uIGV4YWN0bHkgdGhlIHRhc2tzIHRoYXQgbmVlZCB0aGF0IGxhbmd1YWdlIOKAlCBhIHRhc2sgd2l0aCBubyB0cmFuc2Zvcm0sIG9yIG9uZSBpbiBhCiAgICogbGFuZ3VhZ2UgdGhhdCBkaWQgbG9hZCwgc3RpbGwgcnVucyBvbiB0aGlzIHdvcmtlci4KICAgKgogICAqICoqQW5kIHNpbmNlIFcxNDEgdGhlIHNhbWUgaXMgdHJ1ZSBvZiB0aGUgVFlQRSdzIG93biB3b3JrZXI6IHRoaXMgbWV0aG9kIG5ldmVyIHRocm93cyoqIOKAlCBRMjY2LAogICAqIFAzMSBkZWNpc2lvbiAzLCBXNjEncyByb2FkIHRha2VuIGZvciB0aGUgd2hvbGUgb2YgYHNldHVwKClgLiBGMSBpcyBhIGZhY3QgYWJvdXQgVEhJUyBtZXRob2QKICAgKiB0aHJvd2luZywgd2hhdGV2ZXIgdGhyZXcsIGFuZCBXMTQxIG1lYXN1cmVkIGl0IGFnYWluIG9uIDAuNS4yIHRocm91Z2ggYGNyZWF0ZVJ1bnRpbWVgOiB0aHJlZQogICAqIHRhc2tzIG9uIGEgd29ya2VyIHdob3NlIGBzZXR1cCgpYCB0aHJvd3Mgc3RheSBgcGVuZGluZ2AgZm9yIGV2ZXIgaW4gYm90aCBwb29sIG1vZGVzLCB0aGUgcG9vbAogICAqIHJlcXVldWVpbmcgdGhlbSBvbiBlYWNoIHdvcmtlciBmYWlsdXJlIHVudGlsIGl0cyByZXN0YXJ0IGxpbWl0LCBhbmQgdGhlIHJ1bidzIGZvbGQgc2F5cwogICAqIGBydW5uaW5nYC4gU28gZXZlcnkgd2F5IHRoZSB0eXBlJ3Mgd29ya2VyIGNhbiBmYWlsIHRvIHNldCB1cCDigJQgdGhlIG1vZHVsZSBkb2VzIG5vdCBsb2FkLCBpdAogICAqIGV4cG9ydHMgbm8gZGVmYXVsdCBjbGFzcywgaXRzIGNvbnN0cnVjdG9yIHRocm93cywgaXRzIG93biBgc2V0dXAoKWAgdGhyb3dzIOKAlCBhbmQgdGhlIHR3bwogICAqIHBvb2wtY29uZmlnIHJlZnVzYWxzIHRoaXMgbWV0aG9kIG1hZGUgYnkgbmFtZSwgYXJlIFJFTUVNQkVSRUQgaW4gYHNldHVwRmFpbHVyZWAsIGFuZCBgcnVuKClgCiAgICogZmFpbHMgZXZlcnkgdGFzayBvbiB0aGlzIHdvcmtlciB3aXRoIGl0OiBhbiBvcmRpbmFyeSB0YXNrIGZhaWx1cmUsIHdoaWNoIHRoZSBydW4gcm91dGVzIHBlcgogICAqIEFEUiAwMDA0IOKAlCBkb3duIGFuIGBvbjogWyJmYWlsZWQiXWAgZWRnZSBvbiBhbiBvcHRpb25hbCBub2RlLCBwYXJrZWQgYHVzZXJfYWN0aW9uYCBvbiBhCiAgICogbm9uLW9wdGlvbmFsIG9uZS4gKipBIGNvbnN0cnVjdGVkIGlubmVyIHdvcmtlciBpcyB0b3JuIGRvd24gYXQgb25jZSoqLCBiZWNhdXNlIHRoZSBzY2hlZHVsZXIKICAgKiB0ZWFycyBkb3duIGEgd29ya2VyIHdob3NlIGBzZXR1cCgpYCB0aHJldyAoaXRzIG93biByZWZlcmVuY2UsIMKnNjogKmEgZmFpbGluZyBgc2V0dXAoKWAgc3RpbGwKICAgKiB0ZWFycyB0aGUgd29ya2VyIGRvd24qKSBhbmQgdGhpcyBjbGFzcyBpcyBub3cgdGhlIG9ubHkgdGhpbmcgdGhhdCBrbm93cyBvbmUgZGlkLiBUaGUgd29ya2VyCiAgICogc3RheXMgdXAgYW5kIGZhaWxzIGV2ZXJ5IHRhc2sgdW50aWwgdGhlIHBvb2wgaXMgcmVidWlsdDogYSBzZXR1cCB0aGF0IGZhaWxlZCBmb3IgYSB0cmFuc2llbnQKICAgKiByZWFzb24gaXMgbm90IHJldHJpZWQgaGVyZSAoVzE0MSdzIE91dCkuCiAgICovCiAgYXN5bmMgc2V0dXAoKSB7CiAgICB0aGlzLnNldHVwRmFpbHVyZSA9IG51bGw7CiAgICB0cnkgewogICAgICBhd2FpdCB0aGlzLnNldHVwT3JUaHJvdygpOwogICAgfSBjYXRjaCAoZSkgewogICAgICB0aGlzLnNldHVwRmFpbHVyZSA9IG1lc3NhZ2VPZihlKTsKICAgICAgY29uc3QgaW5uZXIgPSB0aGlzLmlubmVyOwogICAgICB0aGlzLmlubmVyID0gbnVsbDsKICAgICAgdGhpcy5ub0lubmVyID0gZmFsc2U7CiAgICAgIHRoaXMubGFuZ3MuY2xlYXIoKTsKICAgICAgaWYgKGlubmVyICE9PSBudWxsKSB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGF3YWl0IGlubmVyLnRlYXJkb3duPy4oKTsKICAgICAgICB9IGNhdGNoICh0KSB7CiAgICAgICAgICB0aGlzLnNldHVwRmFpbHVyZSArPSBgIChhbmQgaXRzIHRlYXJkb3duKCkgYWZ0ZXIgdGhlIGZhaWxlZCBzZXR1cCB0aHJldyB0b286ICR7bWVzc2FnZU9mKHQpfSlgOwogICAgICAgIH0KICAgICAgfQogICAgfQogIH0KICAvKiogV2hhdCBgc2V0dXAoKWAgZGlkIHVudGlsIFcxNDEsIHRocm93cyBhbmQgYWxsOyBgc2V0dXAoKWAgdHVybnMgZWFjaCB0aHJvdyBpbnRvIGBzZXR1cEZhaWx1cmVgLiAqLwogIGFzeW5jIHNldHVwT3JUaHJvdygpIHsKICAgIGlmICh0aGlzLmNmZz8udHJhbnNmb3JtT25seSA9PT0gdHJ1ZSkgewogICAgICBpZiAodGhpcy5jZmcud29ya2VyICE9PSB2b2lkIDApIHsKICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYGVudmVsb3BlIHdvcmtlcjogdGhlIHBvb2wgY29uZmlnIHNheXMgdHJhbnNmb3JtT25seSBBTkQgbmFtZXMgd29ya2VyICR7YnJpZWYodGhpcy5jZmcud29ya2VyKX0gXHUyMDE0IGEgdHlwZSBlaXRoZXIgaGFzIGFuIGlubmVyIHdvcmtlciBvciBvbmx5IHRyYW5zZm9ybXNgKTsKICAgICAgfQogICAgICB0aGlzLm5vSW5uZXIgPSB0cnVlOwogICAgICBmb3IgKGNvbnN0IFtuYW1lLCB1cmxdIG9mIE9iamVjdC5lbnRyaWVzKHRoaXMuY2ZnLmxhbmd1YWdlcyA/PyB7fSkpIHsKICAgICAgICB0aGlzLmxhbmdzLnNldChuYW1lLCBhd2FpdCB0aGlzLmxvYWRMYW5ndWFnZShuYW1lLCB1cmwpKTsKICAgICAgfQogICAgICByZXR1cm47CiAgICB9CiAgICBpZiAodHlwZW9mIHRoaXMuY2ZnPy53b3JrZXIgIT09ICJzdHJpbmciIHx8IHRoaXMuY2ZnLndvcmtlci5sZW5ndGggPT09IDApIHsKICAgICAgdGhyb3cgbmV3IEVycm9yKGBlbnZlbG9wZSB3b3JrZXI6IHRoZSBwb29sIGNvbmZpZyBuYW1lcyBubyB3b3JrZXIgVVJMIFx1MjAxNCBnb3QgJHticmllZih0aGlzLmNmZyl9YCk7CiAgICB9CiAgICBjb25zdCB3b3JrZXJVcmwgPSB0aGlzLmNmZy53b3JrZXI7CiAgICBsZXQgbW9kOwogICAgdHJ5IHsKICAgICAgbW9kID0gYXdhaXQgaW1wb3J0KHdvcmtlclVybCk7CiAgICB9IGNhdGNoIChlKSB7CiAgICAgIHRocm93IG5ldyBFcnJvcihgZW52ZWxvcGUgd29ya2VyOiB0aGUgdHlwZSdzIHdvcmtlciAke0pTT04uc3RyaW5naWZ5KHdvcmtlclVybCl9IGRpZCBub3QgbG9hZDogJHttZXNzYWdlT2YoZSl9YCk7CiAgICB9CiAgICBpZiAodHlwZW9mIG1vZC5kZWZhdWx0ICE9PSAiZnVuY3Rpb24iIHx8ICFtb2QuZGVmYXVsdC5wcm90b3R5cGUpIHsKICAgICAgdGhyb3cgbmV3IEVycm9yKGBlbnZlbG9wZSB3b3JrZXI6IHRoZSB0eXBlJ3Mgd29ya2VyICR7SlNPTi5zdHJpbmdpZnkod29ya2VyVXJsKX0gbXVzdCBleHBvcnQgYSBkZWZhdWx0IGNsYXNzYCk7CiAgICB9CiAgICBjb25zdCBJbm5lciA9IG1vZC5kZWZhdWx0OwogICAgdHJ5IHsKICAgICAgdGhpcy5pbm5lciA9IG5ldyBJbm5lcih0aGlzLmNmZy5jb25maWcgPz8ge30sIHRoaXMud29ya2VyQ29udGV4dCk7CiAgICB9IGNhdGNoIChlKSB7CiAgICAgIHRocm93IG5ldyBFcnJvcihgZW52ZWxvcGUgd29ya2VyOiB0aGUgdHlwZSdzIHdvcmtlciAke0pTT04uc3RyaW5naWZ5KHdvcmtlclVybCl9IHRocmV3IGZyb20gaXRzIGNvbnN0cnVjdG9yOiAke21lc3NhZ2VPZihlKX1gKTsKICAgIH0KICAgIHRyeSB7CiAgICAgIGF3YWl0IHRoaXMuaW5uZXIuc2V0dXA/LigpOwogICAgfSBjYXRjaCAoZSkgewogICAgICB0aHJvdyBuZXcgRXJyb3IoYGVudmVsb3BlIHdvcmtlcjogdGhlIHR5cGUncyB3b3JrZXIgJHtKU09OLnN0cmluZ2lmeSh3b3JrZXJVcmwpfSB0aHJldyBmcm9tIGl0cyBzZXR1cCgpOiAke21lc3NhZ2VPZihlKX1gKTsKICAgIH0KICAgIGZvciAoY29uc3QgW25hbWUsIHVybF0gb2YgT2JqZWN0LmVudHJpZXModGhpcy5jZmcubGFuZ3VhZ2VzID8/IHt9KSkgewogICAgICB0aGlzLmxhbmdzLnNldChuYW1lLCBhd2FpdCB0aGlzLmxvYWRMYW5ndWFnZShuYW1lLCB1cmwpKTsKICAgIH0KICB9CiAgLyoqIE9uZSBsYW5ndWFnZSdzIHdvcmtlciBoYWxmLCBvciB0aGUgRXJyb3IgdGhhdCBzdGFuZHMgaW4gZm9yIGl0IOKAlCBuZXZlciBhIHRocm93IChzZWUgYHNldHVwKClgKS4gKi8KICBhc3luYyBsb2FkTGFuZ3VhZ2UobmFtZSwgdXJsKSB7CiAgICBpZiAodHlwZW9mIHVybCAhPT0gInN0cmluZyIgfHwgdXJsLmxlbmd0aCA9PT0gMCkgewogICAgICByZXR1cm4gbmV3IEVycm9yKGBsYW5ndWFnZSAiJHtuYW1lfSIgbmFtZXMgbm8gd29ya2VyIG1vZHVsZSBVUkwgaW4gdGhlIHBvb2wgY29uZmlnIFx1MjAxNCBnb3QgJHticmllZih1cmwpfWApOwogICAgfQogICAgdHJ5IHsKICAgICAgY29uc3QgbG0gPSBhd2FpdCBpbXBvcnQodXJsKTsKICAgICAgaWYgKHR5cGVvZiBsbS5kZWZhdWx0ICE9PSAiZnVuY3Rpb24iKSB7CiAgICAgICAgcmV0dXJuIG5ldyBFcnJvcihgbGFuZ3VhZ2UgIiR7bmFtZX0iJ3Mgd29ya2VyIG1vZHVsZSAke3VybH0gbXVzdCBleHBvcnQgYSBkZWZhdWx0IGNvbXBpbGUgZnVuY3Rpb24gKGdvdCAke3R5cGVvZiBsbS5kZWZhdWx0fSlgKTsKICAgICAgfQogICAgICByZXR1cm4gbG0uZGVmYXVsdDsKICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgcmV0dXJuIG5ldyBFcnJvcihgbGFuZ3VhZ2UgIiR7bmFtZX0iJ3Mgd29ya2VyIG1vZHVsZSAke3VybH0gZGlkIG5vdCBsb2FkOiAke21lc3NhZ2VPZihlKX1gKTsKICAgIH0KICB9CiAgLyoqCiAgICogYEZELUM1YDogdGhlIGlubmVyIHdvcmtlciByZWNlaXZlcyBgeyBzZXR0aW5ncywgaW5wdXQgfWAgYW5kIG5vdGhpbmcgZWxzZS4gYEZELUM2YDogd2hlbiB0aGUKICAgKiBlbnZlbG9wZSBjYXJyaWVzIGEgYHRyYW5zZm9ybWAsIGBpbnB1dGAgaXMgdGhlIGV2YWx1YXRpb24gb2YgdGhhdCBleHByZXNzaW9uIG92ZXIgdGhlIHZhbHVlCiAgICogcmVjZWl2ZWQsIHdpdGggdGhlIG5vZGUncyBzZXR0aW5ncyBib3VuZCBhcyBgJHNldHRpbmdzYCwgYW5kIHRoZSB0aGlyZCBrZXkgaXMgY29uc3VtZWQgaGVyZS4KICAgKi8KICBhc3luYyBydW4ocGF5bG9hZCwgY29udGV4dCkgewogICAgaWYgKHRoaXMuc2V0dXBGYWlsdXJlICE9PSBudWxsKSB7CiAgICAgIHRocm93IG5ldyBFcnJvcihgJHt0aGlzLnNldHVwRmFpbHVyZX0gXHUyMDE0IGV2ZXJ5IHRhc2sgb24gdGhpcyB3b3JrZXIgZmFpbHMgd2l0aCB0aGlzIHVudGlsIHRoZSBwb29sIGlzIHJlYnVpbHRgKTsKICAgIH0KICAgIGlmICh0aGlzLmlubmVyID09PSBudWxsICYmICF0aGlzLm5vSW5uZXIpIHRocm93IG5ldyBFcnJvcigiZW52ZWxvcGUgd29ya2VyOiBydW4oKSBiZWZvcmUgc2V0dXAoKSBcdTIwMTQgdGhlIGlubmVyIHdvcmtlciBpcyBub3QgbG9hZGVkIik7CiAgICBjb25zdCBlbnYgPSB1bnBhY2tFbnZlbG9wZShwYXlsb2FkKTsKICAgIGlmICh0aGlzLm5vSW5uZXIpIHsKICAgICAgaWYgKGVudi50cmFuc2Zvcm0gPT09IHZvaWQgMCkgewogICAgICAgIHRocm93IG5ldyBOb3RBbkVudmVsb3BlKCJ0eXBlZCBwb29sOiB0aGlzIHBvb2xgcyB0eXBlIG5hbWVzIG5vIHdvcmtlciwgc28gdGhlIGVudmVsb3BlIG11c3QgY2FycnkgYSB0cmFuc2Zvcm0gXHUyMDE0IHRoZXJlIGlzIG5vdGhpbmcgZWxzZSBmb3IgdGhlIHRhc2sgdG8gZG8gKEZELVY0NiByZWZ1c2VzIHN1Y2ggYSBub2RlIGF0IGNvbnN0cnVjdGlvbikiKTsKICAgICAgfQogICAgICByZXR1cm4gYXdhaXQgdGhpcy50cmFuc2Zvcm0oZW52LnRyYW5zZm9ybSwgZW52LmlucHV0LCBlbnYuc2V0dGluZ3MpOwogICAgfQogICAgY29uc3QgaW5wdXQgPSBlbnYudHJhbnNmb3JtID09PSB2b2lkIDAgPyBlbnYuaW5wdXQgOiBhd2FpdCB0aGlzLnRyYW5zZm9ybShlbnYudHJhbnNmb3JtLCBlbnYuaW5wdXQsIGVudi5zZXR0aW5ncyk7CiAgICByZXR1cm4gYXdhaXQgdGhpcy5pbm5lci5ydW4oeyBzZXR0aW5nczogZW52LnNldHRpbmdzLCBpbnB1dCB9LCBjb250ZXh0KTsKICB9CiAgLyoqIEV2YWx1YXRlcyBvbmUgZGVjbGFyZWQgdHJhbnNmb3JtOyBldmVyeSBmYWlsdXJlIGlzIGEgYFRyYW5zZm9ybUZhaWxlZGAgbmFtaW5nIHdoYXQgZmFpbGVkIGFuZCB3aHkuICovCiAgYXN5bmMgdHJhbnNmb3JtKHQsIGlucHV0LCBzZXR0aW5ncykgewogICAgY29uc3QgY29tcGlsZSA9IHRoaXMubGFuZ3MuZ2V0KHQubGFuZyk7CiAgICBpZiAoY29tcGlsZSA9PT0gdm9pZCAwKSB7CiAgICAgIGNvbnN0IGNhcnJpZWQgPSBPYmplY3Qua2V5cyh0aGlzLmNmZy5sYW5ndWFnZXMgPz8ge30pLm1hcCgoeCkgPT4gYCIke3h9ImApLmpvaW4oIiwgIikgfHwgIm5vIGxhbmd1YWdlcyI7CiAgICAgIHRocm93IG5ldyBUcmFuc2Zvcm1GYWlsZWQodCwgdm9pZCAwLCBgbGFuZ3VhZ2UgIiR7dC5sYW5nfSIgaXMgbm90IGxvYWRlZCBpbiB0aGlzIHBvb2wgKHRoZSBwb29sIGNvbmZpZyBjYXJyaWVzICR7Y2FycmllZH0pIFx1MjAxNCB0aGUgYm9vdHN0cmFwIGhlbHBlciB3cml0ZXMgYW4gYWRhcHRlciBVUkwgZm9yIGEgdHlwZSBzb21lIG5vZGUgb2Ygd2hpY2ggZGVjbGFyZXMgYSB0cmFuc2Zvcm0sIGFuZCBuZWVkcyB0aGUgZmxvdyBhbmQgdGhlIGxhbmd1YWdlcyB0byBkbyBpdGApOwogICAgfQogICAgaWYgKGNvbXBpbGUgaW5zdGFuY2VvZiBFcnJvcikgewogICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtRmFpbGVkKHQsIHZvaWQgMCwgYCR7Y29tcGlsZS5tZXNzYWdlfSBcdTIwMTQgZXZlcnkgdGFzayB0cmFuc2Zvcm1pbmcgaW4gIiR7dC5sYW5nfSIgb24gdGhpcyB3b3JrZXIgZmFpbHMgd2l0aCB0aGlzIHVudGlsIHRoZSBwb29sIGlzIHJlYnVpbHRgKTsKICAgIH0KICAgIGNvbnN0IGtleSA9IEpTT04uc3RyaW5naWZ5KFt0LmxhbmcsIHQuZXhwcl0pOwogICAgbGV0IGNvbXBpbGVkID0gdGhpcy5jb21waWxlZC5nZXQoa2V5KTsKICAgIGlmIChjb21waWxlZCA9PT0gdm9pZCAwKSB7CiAgICAgIHRyeSB7CiAgICAgICAgY29tcGlsZWQgPSBjb21waWxlKHQuZXhwcik7CiAgICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtRmFpbGVkKHQsIGNvZGVPZihlKSwgYHRoZSB3b3JrZXIgaGFsZiBvZiAiJHt0Lmxhbmd9IiByZWZ1c2VkIHRoZSBleHByZXNzaW9uIHRoZSByZWdpc3RyeSBoYWxmIGFjY2VwdGVkOiAke21lc3NhZ2VPZihlKX1gKTsKICAgICAgfQogICAgICBpZiAodHlwZW9mIGNvbXBpbGVkPy5ldmFsdWF0ZSAhPT0gImZ1bmN0aW9uIikgewogICAgICAgIHRocm93IG5ldyBUcmFuc2Zvcm1GYWlsZWQodCwgdm9pZCAwLCBgdGhlIHdvcmtlciBoYWxmIG9mICIke3QubGFuZ30iIGNvbXBpbGVkIHRvICR7YnJpZWYoY29tcGlsZWQpfSwgd2hpY2ggaGFzIG5vIGV2YWx1YXRlKGlucHV0LCBzZXR0aW5ncylgKTsKICAgICAgfQogICAgICB0aGlzLmNvbXBpbGVkLnNldChrZXksIGNvbXBpbGVkKTsKICAgIH0KICAgIHRyeSB7CiAgICAgIHJldHVybiBhd2FpdCBjb21waWxlZC5ldmFsdWF0ZShpbnB1dCwgc2V0dGluZ3MpOwogICAgfSBjYXRjaCAoZSkgewogICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtRmFpbGVkKHQsIGNvZGVPZihlKSwgbWVzc2FnZU9mKGUpKTsKICAgIH0KICB9CiAgYXN5bmMgdGVhcmRvd24oKSB7CiAgICBhd2FpdCB0aGlzLmlubmVyPy50ZWFyZG93bj8uKCk7CiAgICB0aGlzLmlubmVyID0gbnVsbDsKICAgIHRoaXMubm9Jbm5lciA9IGZhbHNlOwogICAgdGhpcy5zZXR1cEZhaWx1cmUgPSBudWxsOwogICAgdGhpcy5sYW5ncy5jbGVhcigpOwogICAgdGhpcy5jb21waWxlZC5jbGVhcigpOwogIH0KfTsKZXhwb3J0IHsKICBOb3RBbkVudmVsb3BlLAogIFRyYW5zZm9ybUZhaWxlZCwKICBFbnZlbG9wZVdvcmtlciBhcyBkZWZhdWx0LAogIHVucGFja0VudmVsb3BlCn07Cg==";
34
+ var envelope_worker_default = "data:text/javascript;base64,Ly8gc3JjL3NjaGVkdWxlci9lbnZlbG9wZS13b3JrZXIudHMKdmFyIE5vdEFuRW52ZWxvcGUgPSBjbGFzcyBleHRlbmRzIEVycm9yIHsKfTsKdmFyIFRyYW5zZm9ybUZhaWxlZCA9IGNsYXNzIGV4dGVuZHMgRXJyb3IgewogIGxhbmc7CiAgZXhwcjsKICBjb2RlOwogIGNvbnN0cnVjdG9yKHRyYW5zZm9ybSwgY29kZSwgd2h5KSB7CiAgICBzdXBlcihgdHJhbnNmb3JtIGZhaWxlZCBcdTIwMTQgJHt0cmFuc2Zvcm0ubGFuZ30gJHtKU09OLnN0cmluZ2lmeSh0cmFuc2Zvcm0uZXhwcil9JHtjb2RlICE9PSB2b2lkIDAgPyBgIFske2NvZGV9XWAgOiAiIn06ICR7d2h5fWApOwogICAgdGhpcy5sYW5nID0gdHJhbnNmb3JtLmxhbmc7CiAgICB0aGlzLmV4cHIgPSB0cmFuc2Zvcm0uZXhwcjsKICAgIHRoaXMuY29kZSA9IGNvZGU7CiAgfQp9OwpmdW5jdGlvbiB1bnBhY2tFbnZlbG9wZShwYXlsb2FkKSB7CiAgaWYgKHR5cGVvZiBwYXlsb2FkICE9PSAib2JqZWN0IiB8fCBwYXlsb2FkID09PSBudWxsIHx8IEFycmF5LmlzQXJyYXkocGF5bG9hZCkpIHsKICAgIHRocm93IG5ldyBOb3RBbkVudmVsb3BlKGB0eXBlZCBwb29sOiB0aGUgcGF5bG9hZCBpcyBub3QgYW4gZW52ZWxvcGUgeyBzZXR0aW5ncywgaW5wdXQgfSBcdTIwMTQgZ290ICR7YnJpZWYocGF5bG9hZCl9YCk7CiAgfQogIGNvbnN0IHAgPSBwYXlsb2FkOwogIGZvciAoY29uc3QgayBvZiBbInNldHRpbmdzIiwgImlucHV0Il0pIHsKICAgIGlmICghKGsgaW4gcCkpIHRocm93IG5ldyBOb3RBbkVudmVsb3BlKGB0eXBlZCBwb29sOiB0aGUgcGF5bG9hZCBpcyBub3QgYW4gZW52ZWxvcGUgXHUyMDE0IGl0IGhhcyBubyAiJHtrfSIga2V5IChrZXlzOiAke09iamVjdC5rZXlzKHApLm1hcCgoeCkgPT4gYCIke3h9ImApLmpvaW4oIiwgIikgfHwgIm5vbmUifSlgKTsKICB9CiAgY29uc3Qgc2V0dGluZ3MgPSBwLnNldHRpbmdzOwogIGlmICh0eXBlb2Ygc2V0dGluZ3MgIT09ICJvYmplY3QiIHx8IHNldHRpbmdzID09PSBudWxsIHx8IEFycmF5LmlzQXJyYXkoc2V0dGluZ3MpKSB7CiAgICB0aHJvdyBuZXcgTm90QW5FbnZlbG9wZShgdHlwZWQgcG9vbDogdGhlIGVudmVsb3BlJ3Mgc2V0dGluZ3MgaXMgbm90IGEgcGxhaW4gb2JqZWN0IFx1MjAxNCBnb3QgJHticmllZihzZXR0aW5ncyl9YCk7CiAgfQogIGNvbnN0IGVudiA9IHsgc2V0dGluZ3MsIGlucHV0OiBwLmlucHV0IH07CiAgaWYgKCJ0cmFuc2Zvcm0iIGluIHApIHsKICAgIGNvbnN0IHQgPSBwLnRyYW5zZm9ybTsKICAgIGNvbnN0IHdlbGxGb3JtZWQgPSB0eXBlb2YgdCA9PT0gIm9iamVjdCIgJiYgdCAhPT0gbnVsbCAmJiAhQXJyYXkuaXNBcnJheSh0KSAmJiB0eXBlb2YgdC5sYW5nID09PSAic3RyaW5nIiAmJiB0eXBlb2YgdC5leHByID09PSAic3RyaW5nIiAmJiBPYmplY3Qua2V5cyh0KS5sZW5ndGggPT09IDI7CiAgICBpZiAoIXdlbGxGb3JtZWQpIHRocm93IG5ldyBOb3RBbkVudmVsb3BlKGB0eXBlZCBwb29sOiB0aGUgZW52ZWxvcGUncyB0cmFuc2Zvcm0gaXMgbm90IHsgbGFuZywgZXhwciB9IFx1MjAxNCBnb3QgJHticmllZihwLnRyYW5zZm9ybSl9YCk7CiAgICBlbnYudHJhbnNmb3JtID0geyBsYW5nOiB0LmxhbmcsIGV4cHI6IHQuZXhwciB9OwogIH0KICByZXR1cm4gZW52Owp9CmZ1bmN0aW9uIGJyaWVmKHYpIHsKICBjb25zdCBzID0gcHJpbnRhYmxlKHYpOwogIHJldHVybiBzLmxlbmd0aCA+IDEyMCA/IGAke3Muc2xpY2UoMCwgMTE3KX0uLi5gIDogczsKfQpmdW5jdGlvbiBwcmludGFibGUodikgewogIHRyeSB7CiAgICBjb25zdCBqID0gSlNPTi5zdHJpbmdpZnkodik7CiAgICBpZiAoaiAhPT0gdm9pZCAwKSByZXR1cm4gajsKICB9IGNhdGNoIHsKICB9CiAgdHJ5IHsKICAgIHJldHVybiBTdHJpbmcodik7CiAgfSBjYXRjaCB7CiAgICByZXR1cm4gYGFuIHVucHJpbnRhYmxlICR7dHlwZW9mIHZ9YDsKICB9Cn0KZnVuY3Rpb24gY29kZU9mKGUpIHsKICBjb25zdCBjID0gZT8uY29kZTsKICByZXR1cm4gdHlwZW9mIGMgPT09ICJzdHJpbmciICYmIGMubGVuZ3RoID8gYyA6IHZvaWQgMDsKfQpmdW5jdGlvbiBtZXNzYWdlT2YoZSkgewogIGlmIChlIGluc3RhbmNlb2YgRXJyb3IpIHJldHVybiBlLm1lc3NhZ2U7CiAgdHJ5IHsKICAgIHJldHVybiBTdHJpbmcoZSk7CiAgfSBjYXRjaCB7CiAgICByZXR1cm4gcHJpbnRhYmxlKGUpOwogIH0KfQp2YXIgRW52ZWxvcGVXb3JrZXIgPSBjbGFzcyB7CiAgY2ZnOwogIHdvcmtlckNvbnRleHQ7CiAgaW5uZXIgPSBudWxsOwogIC8qKgogICAqICoqU2V0IGJ5IGBzZXR1cCgpYCB3aGVuIHRoZSBwb29sIGNvbmZpZyBuYW1lcyBubyB3b3JrZXIg4oCUIGEgdHlwZSB0aGF0IG9ubHkgVFJBTlNGT1JNUyoqIChBRFIgMDA3NSkuCiAgICogSXQgaXMgYSBTRVBBUkFURSBmaWVsZCBmcm9tIGBpbm5lciA9PT0gbnVsbGAgb24gcHVycG9zZSwgYW5kIHRoYXQgaXMgdGhlIHdob2xlIG9mIHRoaXMgYXJtJ3MKICAgKiBjb3JyZWN0bmVzczogYGlubmVyYCBpcyBudWxsIGJlZm9yZSBgc2V0dXAoKWAgYW5kIGFmdGVyIGB0ZWFyZG93bigpYCB0b28sIHdoaWNoIGFyZSBMSUZFQ1lDTEUKICAgKiBzdGF0ZXMgYHJ1bigpYCBoYXMgcmVmdXNlZCBieSBuYW1lIHNpbmNlIHYwLjE3LCBzbyByZWFkaW5nIHRoZSBhYnNlbmNlIG9mZiBgaW5uZXJgIHdvdWxkIHR1cm4KICAgKiAqcnVuKCkgYmVmb3JlIHNldHVwKCkqIGludG8gKnJldHVybiB0aGUgaW5wdXQgdW50b3VjaGVkKiDigJQgYSBydW4gdGhhdCBzaWxlbnRseSBoYW5kcyBhIHdvcmtlcidzCiAgICogc3VjY2Vzc29yIHRoZSB3cm9uZyB2YWx1ZSBpbnN0ZWFkIG9mIGZhaWxpbmcgdGhlIHRhc2suIE1lYXN1cmVkIGF0IFcxMDkncyBkZWNsYXJhdGlvbiBzdGVwOiBiZWZvcmUKICAgKiB0aGlzIGl0ZW0gQk9USCBvZiB0aG9zZSBzdGF0ZXMgdGhyZXcsIGFuZCBuZWl0aGVyIHdhcyBhbiBhcm0uCiAgICovCiAgbm9Jbm5lciA9IGZhbHNlOwogIC8qKgogICAqIFRoZSB3b3JrZXIgaGFsZiBvZiBlYWNoIGxhbmd1YWdlIHRoZSBwb29sIGNvbmZpZyBuYW1lcywgbG9hZGVkIGluIGBzZXR1cCgpYCDigJQgb3IgdGhlIHJlYXNvbgogICAqIGl0IGRpZCBub3QgbG9hZCwgUkVNRU1CRVJFRCBzbyB0aGF0IGBydW4oKWAgY2FuIGZhaWwgdGhlIHRhc2sgd2l0aCBpdCAodGhlIG1haW50YWluZXIncyBjYWxsLAogICAqIHNlZSBgc2V0dXAoKWApLgogICAqLwogIGxhbmdzID0gLyogQF9fUFVSRV9fICovIG5ldyBNYXAoKTsKICAvKiogRWFjaCBkaXN0aW5jdCBgKGxhbmcsIGV4cHIpYCBjb21waWxlZCBPTkNFIHBlciB3b3JrZXIgaW5zdGFuY2UsIG5ldmVyIHBlciB0YXNrIOKAlCBQMTcgZGVjaXNpb24gMy4gKi8KICBjb21waWxlZCA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgTWFwKCk7CiAgLyoqCiAgICogKipXaHkgdGhpcyB3b3JrZXIgY291bGQgbm90IHNldCB1cCwgUkVNRU1CRVJFRCDigJQgb3IgYG51bGxgKiog4oCUCiAgICogW1cxNDFdKC4uLy4uL2RvYy93b3JrLWl0ZW1zL3cxNDEtYS13b3JrZXItdGhhdC1jYW5ub3Qtc2V0LXVwLWZhaWxzLWl0cy10YXNrcy1hbmQtdGhlLXJlZ2lzdHJ5LWhhcy1vbmUtc2hhcGUubWQpLAogICAqIFtRMjY2XSguLi8uLi9kb2MvcXVlc3Rpb25zL3EyNjYubWQpLCBQMzEgZGVjaXNpb24gMzogVzYxJ3Mgcm9hZCBmb3IgYSBsYW5ndWFnZSwgdGFrZW4gZm9yIHRoZSB3aG9sZQogICAqIG9mIGBzZXR1cCgpYC4gU2V0IGJ5IGBzZXR1cCgpYCBpbnN0ZWFkIG9mIHRocm93aW5nOyByZWFkIEZJUlNUIGJ5IGBydW4oKWAsIHdoaWNoIGZhaWxzIGV2ZXJ5IHRhc2sKICAgKiB3aXRoIGl0OyBjbGVhcmVkIGJ5IGB0ZWFyZG93bigpYCwgc28gYSB0b3JuLWRvd24gd29ya2VyIGlzIGluIGl0cyBjb25zdHJ1Y3RlZCBzdGF0ZSBhZ2Fpbi4KICAgKi8KICBzZXR1cEZhaWx1cmUgPSBudWxsOwogIC8qKgogICAqIEJvdGggYXJndW1lbnRzIGFyZSBrZXB0LCBhbmQgdGhlIHNlY29uZCBpcyBmb3J3YXJkZWQgdG8gdGhlIGlubmVyIHdvcmtlcjogdGhlIHNjaGVkdWxlciBwYXNzZXMKICAgKiBpdHMgd29ya2VyLWxldmVsIGNvbnRleHQgaGVyZSwgYW5kIGEgd29ya2VyIHRoYXQgb25seSBhY2NlcHRzIGBjb25maWdgIHNpbGVudGx5IGxvc2VzIHRoZQogICAqIGFiaWxpdHkgdG8gc2VsZi10ZXJtaW5hdGUgKHRoZSBzY2hlZHVsZXIncyBvd24gcmVmZXJlbmNlLCDCpzQpLgogICAqLwogIGNvbnN0cnVjdG9yKGNvbmZpZywgd29ya2VyQ29udGV4dCkgewogICAgdGhpcy5jZmcgPSBjb25maWc7CiAgICB0aGlzLndvcmtlckNvbnRleHQgPSB3b3JrZXJDb250ZXh0OwogIH0KICAvKioKICAgKiBMb2FkcyB0aGUgdHlwZSdzIHdvcmtlciBhbmQgcnVucyBJVFMgc2V0dXAg4oCUIGEgbW9kdWxlIHdpdGggbm8gZGVmYXVsdCBjbGFzcyBpcyByZWZ1c2VkIGJ5CiAgICogbmFtZSwgYXMgYXQgdjAuMTcg4oCUIHRoZW4gdGhlIHdvcmtlciBoYWxmIG9mIGV2ZXJ5IGxhbmd1YWdlIHRoZSBwb29sIGNvbmZpZyBuYW1lcywgT05DRSBwZXIKICAgKiB3b3JrZXIgaW5zdGFuY2UgKFAxNyBkZWNpc2lvbiAzKS4KICAgKgogICAqICoqQSBsYW5ndWFnZSBtb2R1bGUgdGhhdCBGQUlMUyBUTyBMT0FEIGRvZXMgbm90IHRocm93IGhlcmU7IHRoZSBmYWlsdXJlIGlzIHJlbWVtYmVyZWQgYW5kCiAgICogZXZlcnkgdGFzayB3aG9zZSB0cmFuc2Zvcm0gbmFtZXMgdGhhdCBsYW5ndWFnZSBmYWlscyBhdCBgcnVuKClgIHdpdGggaXQuKiogTWVhc3VyZWQgYXQgVzYxJ3MKICAgKiBkZWNsYXJhdGlvbiwgYm90aCBydW50aW1lcywgaW5saW5lIGFuZCB0aHJlYWRlZDogYSB3cmFwcGVyIHdob3NlIGBzZXR1cCgpYCB0aHJvd3MgbGVhdmVzIGV2ZXJ5CiAgICogdGFzayBvZiB0aGUgcG9vbCBgcGVuZGluZ2Agd2l0aCBgYXR0ZW1wdHM6IDBgLCB0aGUgcG9vbCByZXN0YXJ0cyBpdHMgd29ya2VyLCBhbmQgdGhlIHNjaGVkdWxlcgogICAqIGVtaXRzIG5vdGhpbmcgYSBkcml2ZXIgY291bGQgdHVybiBpbnRvIGEgcmVjb3JkIOKAlCB0aGUgZmFpbHVyZSBpcyByZXBvcnRlZCBvbiB0aGUgUE9PTCBhcwogICAqIGB3b3JrZXIuc2V0dXAuZmFpbGVkYCBhbmQgYHRhc2sucmVxdWV1ZV9yZXF1aXJlZGAsIGEgd29ya2VyIGVycm9yIGFuZCBub3QgYSB0YXNrJ3MsIHdoaWNoIGlzCiAgICogUDE3IHByZWRpY3Rpb24gMidzIHN0YXRlZCByZXZlcnNhbCBjb25kaXRpb24uIFRoZSBtYWludGFpbmVyIGNob3NlIHRoaXMgcm9hZCBhdCBXNjEncwogICAqIHN0b3AtYW5kLWFzayAoQURSIDAwNTEgcnVsZSA1KTogYSBVUkwgdGhhdCBkb2VzIG5vdCByZXNvbHZlLCBhIG1vZHVsZSB3aXRoIG5vIGRlZmF1bHQgY29tcGlsZQogICAqIGZ1bmN0aW9uLCBvciBhbiBlbXB0eSBVUkwsIGVhY2ggYmVjb21lcyBhIGBUcmFuc2Zvcm1GYWlsZWRgIG5hbWluZyB0aGUgbGFuZ3VhZ2UgYW5kIHRoZSBsb2FkCiAgICogZXJyb3IsIG9uIGV4YWN0bHkgdGhlIHRhc2tzIHRoYXQgbmVlZCB0aGF0IGxhbmd1YWdlIOKAlCBhIHRhc2sgd2l0aCBubyB0cmFuc2Zvcm0sIG9yIG9uZSBpbiBhCiAgICogbGFuZ3VhZ2UgdGhhdCBkaWQgbG9hZCwgc3RpbGwgcnVucyBvbiB0aGlzIHdvcmtlci4KICAgKgogICAqICoqQW5kIHNpbmNlIFcxNDEgdGhlIHNhbWUgaXMgdHJ1ZSBvZiB0aGUgVFlQRSdzIG93biB3b3JrZXI6IHRoaXMgbWV0aG9kIG5ldmVyIHRocm93cyoqIOKAlCBRMjY2LAogICAqIFAzMSBkZWNpc2lvbiAzLCBXNjEncyByb2FkIHRha2VuIGZvciB0aGUgd2hvbGUgb2YgYHNldHVwKClgLiBGMSBpcyBhIGZhY3QgYWJvdXQgVEhJUyBtZXRob2QKICAgKiB0aHJvd2luZywgd2hhdGV2ZXIgdGhyZXcsIGFuZCBXMTQxIG1lYXN1cmVkIGl0IGFnYWluIG9uIDAuNS4yIHRocm91Z2ggYGNyZWF0ZVJ1bnRpbWVgOiB0aHJlZQogICAqIHRhc2tzIG9uIGEgd29ya2VyIHdob3NlIGBzZXR1cCgpYCB0aHJvd3Mgc3RheSBgcGVuZGluZ2AgZm9yIGV2ZXIgaW4gYm90aCBwb29sIG1vZGVzLCB0aGUgcG9vbAogICAqIHJlcXVldWVpbmcgdGhlbSBvbiBlYWNoIHdvcmtlciBmYWlsdXJlIHVudGlsIGl0cyByZXN0YXJ0IGxpbWl0LCBhbmQgdGhlIHJ1bidzIGZvbGQgc2F5cwogICAqIGBydW5uaW5nYC4gU28gZXZlcnkgd2F5IHRoZSB0eXBlJ3Mgd29ya2VyIGNhbiBmYWlsIHRvIHNldCB1cCDigJQgdGhlIG1vZHVsZSBkb2VzIG5vdCBsb2FkLCBpdAogICAqIGV4cG9ydHMgbm8gZGVmYXVsdCBjbGFzcywgaXRzIGNvbnN0cnVjdG9yIHRocm93cywgaXRzIG93biBgc2V0dXAoKWAgdGhyb3dzIOKAlCBhbmQgdGhlIHR3bwogICAqIHBvb2wtY29uZmlnIHJlZnVzYWxzIHRoaXMgbWV0aG9kIG1hZGUgYnkgbmFtZSwgYXJlIFJFTUVNQkVSRUQgaW4gYHNldHVwRmFpbHVyZWAsIGFuZCBgcnVuKClgCiAgICogZmFpbHMgZXZlcnkgdGFzayBvbiB0aGlzIHdvcmtlciB3aXRoIGl0OiBhbiBvcmRpbmFyeSB0YXNrIGZhaWx1cmUsIHdoaWNoIHRoZSBydW4gcm91dGVzIHBlcgogICAqIEFEUiAwMDA0IOKAlCBkb3duIGFuIGBvbjogWyJmYWlsZWQiXWAgZWRnZSBvbiBhbiBvcHRpb25hbCBub2RlLCBwYXJrZWQgYHVzZXJfYWN0aW9uYCBvbiBhCiAgICogbm9uLW9wdGlvbmFsIG9uZS4gKipBIGNvbnN0cnVjdGVkIGlubmVyIHdvcmtlciBpcyB0b3JuIGRvd24gYXQgb25jZSoqLCBiZWNhdXNlIHRoZSBzY2hlZHVsZXIKICAgKiB0ZWFycyBkb3duIGEgd29ya2VyIHdob3NlIGBzZXR1cCgpYCB0aHJldyAoaXRzIG93biByZWZlcmVuY2UsIMKnNjogKmEgZmFpbGluZyBgc2V0dXAoKWAgc3RpbGwKICAgKiB0ZWFycyB0aGUgd29ya2VyIGRvd24qKSBhbmQgdGhpcyBjbGFzcyBpcyBub3cgdGhlIG9ubHkgdGhpbmcgdGhhdCBrbm93cyBvbmUgZGlkLiBUaGUgd29ya2VyCiAgICogc3RheXMgdXAgYW5kIGZhaWxzIGV2ZXJ5IHRhc2sgdW50aWwgdGhlIHBvb2wgaXMgcmVidWlsdDogYSBzZXR1cCB0aGF0IGZhaWxlZCBmb3IgYSB0cmFuc2llbnQKICAgKiByZWFzb24gaXMgbm90IHJldHJpZWQgaGVyZSAoVzE0MSdzIE91dCkuCiAgICovCiAgYXN5bmMgc2V0dXAoKSB7CiAgICB0aGlzLnNldHVwRmFpbHVyZSA9IG51bGw7CiAgICB0cnkgewogICAgICBhd2FpdCB0aGlzLnNldHVwT3JUaHJvdygpOwogICAgfSBjYXRjaCAoZSkgewogICAgICB0aGlzLnNldHVwRmFpbHVyZSA9IG1lc3NhZ2VPZihlKTsKICAgICAgY29uc3QgaW5uZXIgPSB0aGlzLmlubmVyOwogICAgICB0aGlzLmlubmVyID0gbnVsbDsKICAgICAgdGhpcy5ub0lubmVyID0gZmFsc2U7CiAgICAgIHRoaXMubGFuZ3MuY2xlYXIoKTsKICAgICAgaWYgKGlubmVyICE9PSBudWxsKSB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGF3YWl0IGlubmVyLnRlYXJkb3duPy4oKTsKICAgICAgICB9IGNhdGNoICh0KSB7CiAgICAgICAgICB0aGlzLnNldHVwRmFpbHVyZSArPSBgIChhbmQgaXRzIHRlYXJkb3duKCkgYWZ0ZXIgdGhlIGZhaWxlZCBzZXR1cCB0aHJldyB0b286ICR7bWVzc2FnZU9mKHQpfSlgOwogICAgICAgIH0KICAgICAgfQogICAgfQogIH0KICAvKiogV2hhdCBgc2V0dXAoKWAgZGlkIHVudGlsIFcxNDEsIHRocm93cyBhbmQgYWxsOyBgc2V0dXAoKWAgdHVybnMgZWFjaCB0aHJvdyBpbnRvIGBzZXR1cEZhaWx1cmVgLiAqLwogIGFzeW5jIHNldHVwT3JUaHJvdygpIHsKICAgIGlmICh0aGlzLmNmZz8udHJhbnNmb3JtT25seSA9PT0gdHJ1ZSkgewogICAgICBpZiAodGhpcy5jZmcud29ya2VyICE9PSB2b2lkIDApIHsKICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYGVudmVsb3BlIHdvcmtlcjogdGhlIHBvb2wgY29uZmlnIHNheXMgdHJhbnNmb3JtT25seSBBTkQgbmFtZXMgd29ya2VyICR7YnJpZWYodGhpcy5jZmcud29ya2VyKX0gXHUyMDE0IGEgdHlwZSBlaXRoZXIgaGFzIGFuIGlubmVyIHdvcmtlciBvciBvbmx5IHRyYW5zZm9ybXNgKTsKICAgICAgfQogICAgICB0aGlzLm5vSW5uZXIgPSB0cnVlOwogICAgICBmb3IgKGNvbnN0IFtuYW1lLCB1cmxdIG9mIE9iamVjdC5lbnRyaWVzKHRoaXMuY2ZnLmxhbmd1YWdlcyA/PyB7fSkpIHsKICAgICAgICB0aGlzLmxhbmdzLnNldChuYW1lLCBhd2FpdCB0aGlzLmxvYWRMYW5ndWFnZShuYW1lLCB1cmwpKTsKICAgICAgfQogICAgICByZXR1cm47CiAgICB9CiAgICBpZiAodHlwZW9mIHRoaXMuY2ZnPy53b3JrZXIgIT09ICJzdHJpbmciIHx8IHRoaXMuY2ZnLndvcmtlci5sZW5ndGggPT09IDApIHsKICAgICAgdGhyb3cgbmV3IEVycm9yKGBlbnZlbG9wZSB3b3JrZXI6IHRoZSBwb29sIGNvbmZpZyBuYW1lcyBubyB3b3JrZXIgVVJMIFx1MjAxNCBnb3QgJHticmllZih0aGlzLmNmZyl9YCk7CiAgICB9CiAgICBjb25zdCB3b3JrZXJVcmwgPSB0aGlzLmNmZy53b3JrZXI7CiAgICBsZXQgbW9kOwogICAgdHJ5IHsKICAgICAgbW9kID0gYXdhaXQgaW1wb3J0KHdvcmtlclVybCk7CiAgICB9IGNhdGNoIChlKSB7CiAgICAgIHRocm93IG5ldyBFcnJvcihgZW52ZWxvcGUgd29ya2VyOiB0aGUgdHlwZSdzIHdvcmtlciAke0pTT04uc3RyaW5naWZ5KHdvcmtlclVybCl9IGRpZCBub3QgbG9hZDogJHttZXNzYWdlT2YoZSl9YCk7CiAgICB9CiAgICBpZiAodHlwZW9mIG1vZC5kZWZhdWx0ICE9PSAiZnVuY3Rpb24iIHx8ICFtb2QuZGVmYXVsdC5wcm90b3R5cGUpIHsKICAgICAgdGhyb3cgbmV3IEVycm9yKGBlbnZlbG9wZSB3b3JrZXI6IHRoZSB0eXBlJ3Mgd29ya2VyICR7SlNPTi5zdHJpbmdpZnkod29ya2VyVXJsKX0gbXVzdCBleHBvcnQgYSBkZWZhdWx0IGNsYXNzYCk7CiAgICB9CiAgICBjb25zdCBJbm5lciA9IG1vZC5kZWZhdWx0OwogICAgdHJ5IHsKICAgICAgdGhpcy5pbm5lciA9IG5ldyBJbm5lcih0aGlzLmNmZy5jb25maWcgPz8ge30sIHRoaXMud29ya2VyQ29udGV4dCk7CiAgICB9IGNhdGNoIChlKSB7CiAgICAgIHRocm93IG5ldyBFcnJvcihgZW52ZWxvcGUgd29ya2VyOiB0aGUgdHlwZSdzIHdvcmtlciAke0pTT04uc3RyaW5naWZ5KHdvcmtlclVybCl9IHRocmV3IGZyb20gaXRzIGNvbnN0cnVjdG9yOiAke21lc3NhZ2VPZihlKX1gKTsKICAgIH0KICAgIHRyeSB7CiAgICAgIGF3YWl0IHRoaXMuaW5uZXIuc2V0dXA/LigpOwogICAgfSBjYXRjaCAoZSkgewogICAgICB0aHJvdyBuZXcgRXJyb3IoYGVudmVsb3BlIHdvcmtlcjogdGhlIHR5cGUncyB3b3JrZXIgJHtKU09OLnN0cmluZ2lmeSh3b3JrZXJVcmwpfSB0aHJldyBmcm9tIGl0cyBzZXR1cCgpOiAke21lc3NhZ2VPZihlKX1gKTsKICAgIH0KICAgIGZvciAoY29uc3QgW25hbWUsIHVybF0gb2YgT2JqZWN0LmVudHJpZXModGhpcy5jZmcubGFuZ3VhZ2VzID8/IHt9KSkgewogICAgICB0aGlzLmxhbmdzLnNldChuYW1lLCBhd2FpdCB0aGlzLmxvYWRMYW5ndWFnZShuYW1lLCB1cmwpKTsKICAgIH0KICB9CiAgLyoqIE9uZSBsYW5ndWFnZSdzIHdvcmtlciBoYWxmLCBvciB0aGUgRXJyb3IgdGhhdCBzdGFuZHMgaW4gZm9yIGl0IOKAlCBuZXZlciBhIHRocm93IChzZWUgYHNldHVwKClgKS4gKi8KICBhc3luYyBsb2FkTGFuZ3VhZ2UobmFtZSwgdXJsKSB7CiAgICBpZiAodHlwZW9mIHVybCAhPT0gInN0cmluZyIgfHwgdXJsLmxlbmd0aCA9PT0gMCkgewogICAgICByZXR1cm4gbmV3IEVycm9yKGBsYW5ndWFnZSAiJHtuYW1lfSIgbmFtZXMgbm8gd29ya2VyIG1vZHVsZSBVUkwgaW4gdGhlIHBvb2wgY29uZmlnIFx1MjAxNCBnb3QgJHticmllZih1cmwpfWApOwogICAgfQogICAgdHJ5IHsKICAgICAgY29uc3QgbG0gPSBhd2FpdCBpbXBvcnQodXJsKTsKICAgICAgaWYgKHR5cGVvZiBsbS5kZWZhdWx0ICE9PSAiZnVuY3Rpb24iKSB7CiAgICAgICAgcmV0dXJuIG5ldyBFcnJvcihgbGFuZ3VhZ2UgIiR7bmFtZX0iJ3Mgd29ya2VyIG1vZHVsZSAke3VybH0gbXVzdCBleHBvcnQgYSBkZWZhdWx0IGNvbXBpbGUgZnVuY3Rpb24gKGdvdCAke3R5cGVvZiBsbS5kZWZhdWx0fSlgKTsKICAgICAgfQogICAgICByZXR1cm4gbG0uZGVmYXVsdDsKICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgcmV0dXJuIG5ldyBFcnJvcihgbGFuZ3VhZ2UgIiR7bmFtZX0iJ3Mgd29ya2VyIG1vZHVsZSAke3VybH0gZGlkIG5vdCBsb2FkOiAke21lc3NhZ2VPZihlKX1gKTsKICAgIH0KICB9CiAgLyoqCiAgICogYEZELUM1YDogdGhlIGlubmVyIHdvcmtlciByZWNlaXZlcyBgeyBzZXR0aW5ncywgaW5wdXQgfWAgYXMgaXRzIHBheWxvYWQsIGFuZCB0aGUgc2NoZWR1bGVyJ3MgdGFzayBjb250ZXh0IGFzIGl0cwogICAqIHNlY29uZCBhcmd1bWVudCwgcGFzc2VkIHRocm91Z2ggdW50b3VjaGVkIChXMTU5KS4gYEZELUM2YDogd2hlbiB0aGUKICAgKiBlbnZlbG9wZSBjYXJyaWVzIGEgYHRyYW5zZm9ybWAsIGBpbnB1dGAgaXMgdGhlIGV2YWx1YXRpb24gb2YgdGhhdCBleHByZXNzaW9uIG92ZXIgdGhlIHZhbHVlCiAgICogcmVjZWl2ZWQsIHdpdGggdGhlIG5vZGUncyBzZXR0aW5ncyBib3VuZCBhcyBgJHNldHRpbmdzYCwgYW5kIHRoZSB0aGlyZCBrZXkgaXMgY29uc3VtZWQgaGVyZS4KICAgKi8KICBhc3luYyBydW4ocGF5bG9hZCwgY29udGV4dCkgewogICAgaWYgKHRoaXMuc2V0dXBGYWlsdXJlICE9PSBudWxsKSB7CiAgICAgIHRocm93IG5ldyBFcnJvcihgJHt0aGlzLnNldHVwRmFpbHVyZX0gXHUyMDE0IGV2ZXJ5IHRhc2sgb24gdGhpcyB3b3JrZXIgZmFpbHMgd2l0aCB0aGlzIHVudGlsIHRoZSBwb29sIGlzIHJlYnVpbHRgKTsKICAgIH0KICAgIGlmICh0aGlzLmlubmVyID09PSBudWxsICYmICF0aGlzLm5vSW5uZXIpIHRocm93IG5ldyBFcnJvcigiZW52ZWxvcGUgd29ya2VyOiBydW4oKSBiZWZvcmUgc2V0dXAoKSBcdTIwMTQgdGhlIGlubmVyIHdvcmtlciBpcyBub3QgbG9hZGVkIik7CiAgICBjb25zdCBlbnYgPSB1bnBhY2tFbnZlbG9wZShwYXlsb2FkKTsKICAgIGlmICh0aGlzLm5vSW5uZXIpIHsKICAgICAgaWYgKGVudi50cmFuc2Zvcm0gPT09IHZvaWQgMCkgewogICAgICAgIHRocm93IG5ldyBOb3RBbkVudmVsb3BlKCJ0eXBlZCBwb29sOiB0aGlzIHBvb2xgcyB0eXBlIG5hbWVzIG5vIHdvcmtlciwgc28gdGhlIGVudmVsb3BlIG11c3QgY2FycnkgYSB0cmFuc2Zvcm0gXHUyMDE0IHRoZXJlIGlzIG5vdGhpbmcgZWxzZSBmb3IgdGhlIHRhc2sgdG8gZG8gKEZELVY0NiByZWZ1c2VzIHN1Y2ggYSBub2RlIGF0IGNvbnN0cnVjdGlvbikiKTsKICAgICAgfQogICAgICByZXR1cm4gYXdhaXQgdGhpcy50cmFuc2Zvcm0oZW52LnRyYW5zZm9ybSwgZW52LmlucHV0LCBlbnYuc2V0dGluZ3MpOwogICAgfQogICAgY29uc3QgaW5wdXQgPSBlbnYudHJhbnNmb3JtID09PSB2b2lkIDAgPyBlbnYuaW5wdXQgOiBhd2FpdCB0aGlzLnRyYW5zZm9ybShlbnYudHJhbnNmb3JtLCBlbnYuaW5wdXQsIGVudi5zZXR0aW5ncyk7CiAgICByZXR1cm4gYXdhaXQgdGhpcy5pbm5lci5ydW4oeyBzZXR0aW5nczogZW52LnNldHRpbmdzLCBpbnB1dCB9LCBjb250ZXh0KTsKICB9CiAgLyoqIEV2YWx1YXRlcyBvbmUgZGVjbGFyZWQgdHJhbnNmb3JtOyBldmVyeSBmYWlsdXJlIGlzIGEgYFRyYW5zZm9ybUZhaWxlZGAgbmFtaW5nIHdoYXQgZmFpbGVkIGFuZCB3aHkuICovCiAgYXN5bmMgdHJhbnNmb3JtKHQsIGlucHV0LCBzZXR0aW5ncykgewogICAgY29uc3QgY29tcGlsZSA9IHRoaXMubGFuZ3MuZ2V0KHQubGFuZyk7CiAgICBpZiAoY29tcGlsZSA9PT0gdm9pZCAwKSB7CiAgICAgIGNvbnN0IGNhcnJpZWQgPSBPYmplY3Qua2V5cyh0aGlzLmNmZy5sYW5ndWFnZXMgPz8ge30pLm1hcCgoeCkgPT4gYCIke3h9ImApLmpvaW4oIiwgIikgfHwgIm5vIGxhbmd1YWdlcyI7CiAgICAgIHRocm93IG5ldyBUcmFuc2Zvcm1GYWlsZWQodCwgdm9pZCAwLCBgbGFuZ3VhZ2UgIiR7dC5sYW5nfSIgaXMgbm90IGxvYWRlZCBpbiB0aGlzIHBvb2wgKHRoZSBwb29sIGNvbmZpZyBjYXJyaWVzICR7Y2FycmllZH0pIFx1MjAxNCB0aGUgYm9vdHN0cmFwIGhlbHBlciB3cml0ZXMgZXZlcnkgbGFuZ3VhZ2UgaXQgaXMgZ2l2ZW4gaW50byBldmVyeSBwb29sLCBzbyB0aGlzIG9uZSB3YXMgbm90IGluIHRoZSByZWdpc3RyeSB0aGUgcG9vbCB3YXMgYnVpbHQgZnJvbWApOwogICAgfQogICAgaWYgKGNvbXBpbGUgaW5zdGFuY2VvZiBFcnJvcikgewogICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtRmFpbGVkKHQsIHZvaWQgMCwgYCR7Y29tcGlsZS5tZXNzYWdlfSBcdTIwMTQgZXZlcnkgdGFzayB0cmFuc2Zvcm1pbmcgaW4gIiR7dC5sYW5nfSIgb24gdGhpcyB3b3JrZXIgZmFpbHMgd2l0aCB0aGlzIHVudGlsIHRoZSBwb29sIGlzIHJlYnVpbHRgKTsKICAgIH0KICAgIGNvbnN0IGtleSA9IEpTT04uc3RyaW5naWZ5KFt0LmxhbmcsIHQuZXhwcl0pOwogICAgbGV0IGNvbXBpbGVkID0gdGhpcy5jb21waWxlZC5nZXQoa2V5KTsKICAgIGlmIChjb21waWxlZCA9PT0gdm9pZCAwKSB7CiAgICAgIHRyeSB7CiAgICAgICAgY29tcGlsZWQgPSBjb21waWxlKHQuZXhwcik7CiAgICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtRmFpbGVkKHQsIGNvZGVPZihlKSwgYHRoZSB3b3JrZXIgaGFsZiBvZiAiJHt0Lmxhbmd9IiByZWZ1c2VkIHRoZSBleHByZXNzaW9uIHRoZSByZWdpc3RyeSBoYWxmIGFjY2VwdGVkOiAke21lc3NhZ2VPZihlKX1gKTsKICAgICAgfQogICAgICBpZiAodHlwZW9mIGNvbXBpbGVkPy5ldmFsdWF0ZSAhPT0gImZ1bmN0aW9uIikgewogICAgICAgIHRocm93IG5ldyBUcmFuc2Zvcm1GYWlsZWQodCwgdm9pZCAwLCBgdGhlIHdvcmtlciBoYWxmIG9mICIke3QubGFuZ30iIGNvbXBpbGVkIHRvICR7YnJpZWYoY29tcGlsZWQpfSwgd2hpY2ggaGFzIG5vIGV2YWx1YXRlKGlucHV0LCBzZXR0aW5ncylgKTsKICAgICAgfQogICAgICB0aGlzLmNvbXBpbGVkLnNldChrZXksIGNvbXBpbGVkKTsKICAgIH0KICAgIHRyeSB7CiAgICAgIHJldHVybiBhd2FpdCBjb21waWxlZC5ldmFsdWF0ZShpbnB1dCwgc2V0dGluZ3MpOwogICAgfSBjYXRjaCAoZSkgewogICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtRmFpbGVkKHQsIGNvZGVPZihlKSwgbWVzc2FnZU9mKGUpKTsKICAgIH0KICB9CiAgYXN5bmMgdGVhcmRvd24oKSB7CiAgICBhd2FpdCB0aGlzLmlubmVyPy50ZWFyZG93bj8uKCk7CiAgICB0aGlzLmlubmVyID0gbnVsbDsKICAgIHRoaXMubm9Jbm5lciA9IGZhbHNlOwogICAgdGhpcy5zZXR1cEZhaWx1cmUgPSBudWxsOwogICAgdGhpcy5sYW5ncy5jbGVhcigpOwogICAgdGhpcy5jb21waWxlZC5jbGVhcigpOwogIH0KfTsKZXhwb3J0IHsKICBOb3RBbkVudmVsb3BlLAogIFRyYW5zZm9ybUZhaWxlZCwKICBFbnZlbG9wZVdvcmtlciBhcyBkZWZhdWx0LAogIHVucGFja0VudmVsb3BlCn07Cg==";
32
35
 
33
36
  // src/scheduler/bootstrap.ts
34
37
  var ENVELOPE_WORKER_URL = envelope_worker_default;
35
38
  var BootstrapError = class extends Error {
36
39
  };
37
40
  var defaultCreatePool = (scriptUrl, options) => new WorkerManager(scriptUrl, options);
38
- function transformLanguagesByType(flows) {
39
- const out = /* @__PURE__ */ new Map();
40
- for (const flow of flows) {
41
- for (const n of flow.nodes) {
42
- if (n.kind !== "task") continue;
43
- const t = n;
44
- if (t.type === void 0 || t.transform === void 0) continue;
45
- let set = out.get(t.type);
46
- if (set === void 0) {
47
- set = /* @__PURE__ */ new Set();
48
- out.set(t.type, set);
49
- }
50
- set.add(t.transform.lang);
51
- }
52
- }
53
- return out;
54
- }
55
41
  function bootstrap(registry, groups = {}, options = {}) {
56
42
  checkRegistry(registry);
57
43
  const workers = workersOf(registry.workers);
@@ -68,7 +54,7 @@ function bootstrap(registry, groups = {}, options = {}) {
68
54
  for (const [key, inst] of named) {
69
55
  const entry = types.get(inst.type);
70
56
  const def = isDerivation(entry) ? entry : nodeTypeFromDeclaration(entry);
71
- derived[key] = derivePool(key, inst.type, def, def.worker === void 0 ? void 0 : workers.get(def.worker), inst.config, groupKeys, ConfigRefused);
57
+ derived[key] = derivePool(key, inst.type, def, def.worker === void 0 ? void 0 : workers.get(def.worker), inst.config, groupKeys, ConfigRefused, inst.pool);
72
58
  }
73
59
  for (const [name, entry] of types) if (builtIn(name)) one(name, name, entry, (isDerivation(entry) ? entry : nodeTypeFromDeclaration(entry)).config, TypeDefaultRefused);
74
60
  const namedByPools = /* @__PURE__ */ new Set();
@@ -79,28 +65,18 @@ function bootstrap(registry, groups = {}, options = {}) {
79
65
  }
80
66
  }
81
67
  const adapters = languagesOf(options.languages);
82
- const byType = transformLanguagesByType(options.flows ?? []);
83
- const languagesFor = /* @__PURE__ */ new Map();
84
- for (const [name] of types) {
85
- const langs = byType.get(name);
86
- if (langs === void 0 || langs.size === 0) continue;
87
- const urls = {};
88
- for (const lang of [...langs].sort()) {
89
- const adapter = adapters.get(lang);
90
- if (adapter === void 0) {
91
- throw new BootstrapError(`node type "${name}" has a node declaring transform.lang "${lang}", and no adapter was given for it (given: ${[...adapters.keys()].sort().map((x) => `"${x}"`).join(", ") || "none"}) \u2014 the wrapper would meet the transform with nothing to evaluate it`);
92
- }
93
- if (typeof adapter.worker !== "string" || adapter.worker.length === 0) {
94
- throw new BootstrapError(`language "${lang}" names no worker module URL \u2014 LanguageAdapter.worker is the URL of the module whose default export compiles and evaluates it; a function cannot cross to a thread`);
95
- }
96
- urls[lang] = adapter.worker;
68
+ let languages;
69
+ for (const lang of [...adapters.keys()].sort()) {
70
+ const adapter = adapters.get(lang);
71
+ if (typeof adapter?.worker !== "string" || adapter.worker.length === 0) {
72
+ throw new BootstrapError(`language "${lang}" names no worker module URL \u2014 LanguageAdapter.worker is the URL of the module whose default export compiles and evaluates it; a function cannot cross to a thread`);
97
73
  }
98
- languagesFor.set(name, urls);
74
+ (languages ??= {})[lang] = adapter.worker;
99
75
  }
100
76
  const createPool = options.createPool ?? defaultCreatePool;
101
77
  const workerPools = {};
102
78
  for (const [key, p] of Object.entries(derived)) {
103
- workerPools[key] = createPool(ENVELOPE_WORKER_URL, poolOptionsOf(p.spec, p.definition.inline, p.worker?.url, languagesFor.get(p.type)));
79
+ workerPools[key] = createPool(ENVELOPE_WORKER_URL, poolOptionsOf(p.spec, p.definition.inline, p.worker?.url, languages === void 0 ? void 0 : { ...languages }));
104
80
  }
105
81
  return { workerPools, resourceGroups: { ...groups }, derived };
106
82
  }
@@ -122,10 +98,11 @@ var GroupUnusable = class extends RuntimeError {
122
98
  };
123
99
  var GroupNotBuildable = class extends RuntimeError {
124
100
  };
125
- var LanguageNotBuilt = class extends RuntimeError {
126
- };
127
101
  var RunIdInUse = class extends RuntimeError {
128
102
  };
103
+ var LimitKeyMissing = class extends RuntimeError {
104
+ };
105
+ var KEYED_RULE = "FD-R6";
129
106
  var BUILT_IN_GROUP_FACTORIES = {
130
107
  ConcurrentLimitGroup: (config, key) => new ConcurrentLimitGroup(config.limit, key),
131
108
  RateLimitGroup: (config, key) => new RateLimitGroup(config.windows, key),
@@ -161,6 +138,10 @@ function checkGroup(key, typeName, group) {
161
138
  return group;
162
139
  }
163
140
  function createRuntime(document, code = {}, options = {}) {
141
+ if (options.defaultRetryPolicy !== void 0) {
142
+ const problem = retryPolicyProblem(options.defaultRetryPolicy);
143
+ if (problem !== null) throw new InvalidDefinition(["FD-V30"], `defaultRetryPolicy is not a RetryPolicy \u2014 FD-V30: ${problem}`);
144
+ }
164
145
  const resolved = resolveRegistry(document, code);
165
146
  const suppliedPredicateNames = code.predicates === void 0 ? [] : code.predicates instanceof Map ? [...code.predicates.keys()] : code.predicates instanceof Set ? [...code.predicates] : Array.isArray(code.predicates) ? [...code.predicates] : Object.keys(code.predicates);
166
147
  for (const [what, named, given] of [
@@ -192,7 +173,7 @@ function createRuntime(document, code = {}, options = {}) {
192
173
  const nodeTypes = {};
193
174
  for (const [name, def] of resolved.nodeTypes) nodeTypes[name] = def;
194
175
  const pools = {};
195
- for (const [key, p] of resolved.pools) if (key !== p.type) pools[key] = { type: p.type, config: p.config };
176
+ for (const [key, p] of resolved.pools) if (key !== p.type) pools[key] = { type: p.type, config: p.config, ...p.pool !== void 0 ? { pool: p.pool } : {} };
196
177
  const languages = {};
197
178
  for (const [name, adapter] of resolved.languages) languages[name] = adapter;
198
179
  const namedByPools = {};
@@ -201,8 +182,7 @@ function createRuntime(document, code = {}, options = {}) {
201
182
  }
202
183
  const built = bootstrap({ workers, nodeTypes, pools }, namedByPools, {
203
184
  ...options.createPool !== void 0 ? { createPool: options.createPool } : {},
204
- languages,
205
- flows: options.flows ?? []
185
+ languages
206
186
  });
207
187
  const scheduler = (options.createScheduler ?? ((p, g) => new FyflowScheduler(p, g)))(built.workerPools, groups);
208
188
  const predicates = /* @__PURE__ */ new Map();
@@ -220,7 +200,40 @@ function createRuntime(document, code = {}, options = {}) {
220
200
  languages,
221
201
  ...code.gateTypes !== void 0 ? { gateTypes: code.gateTypes } : {}
222
202
  };
223
- const builtLanguages = transformLanguagesByType(options.flows ?? []);
203
+ const validatorRegistry = {
204
+ predicates: new Set(predicates.keys()),
205
+ groups: new Set(registry.groups ?? []),
206
+ nodeTypes: nodeTypesOf(registry.nodeTypes),
207
+ languages: languagesOf(registry.languages),
208
+ workers: workersOf(registry.workers),
209
+ pools: poolsOf(registry.pools),
210
+ ...registry.gateTypes !== void 0 ? { gateTypes: registry.gateTypes } : {}
211
+ };
212
+ const keyedByBuiltIn = /* @__PURE__ */ new Set();
213
+ for (const [key, g] of resolved.groups) if (g.type === "KeyedRateLimitGroup") keyedByBuiltIn.add(key);
214
+ const keyedFindings = (flow) => {
215
+ const nodes = flow?.nodes;
216
+ if (keyedByBuiltIn.size === 0 || typeof nodes?.[Symbol.iterator] !== "function") return [];
217
+ const out = [];
218
+ for (const node of nodes) {
219
+ if (typeof node !== "object" || node === null) continue;
220
+ const n = node;
221
+ if (n.kind !== "task") continue;
222
+ const poolKey = typeof n.pool === "string" ? n.pool : typeof n.type === "string" ? n.type : void 0;
223
+ const fromPool = poolKey === void 0 ? [] : resolved.pools.get(poolKey)?.spec.groups ?? [];
224
+ const fromNode = Array.isArray(n.workerGroups) ? n.workerGroups.filter((g) => typeof g === "string") : [];
225
+ const reached = [.../* @__PURE__ */ new Set([...fromPool, ...fromNode])].filter((g) => keyedByBuiltIn.has(g)).sort();
226
+ if (reached.length === 0) continue;
227
+ const at = typeof n.id === "string" ? n.id : null;
228
+ out.push({
229
+ rule: KEYED_RULE,
230
+ at,
231
+ detail: `node ${at === null ? "<unnamed>" : q(at)} reaches keyed group${reached.length > 1 ? "s" : ""} ${reached.map(q).join(", ")}, built by the built-in KeyedRateLimitGroup factory with no keyFrom \u2014 so every task of it needs a limitKey, which nothing sets unless start is given a createTask, and without one the scheduler's addTask throws "Missing limit key". Two roads work: pass start a createTask that sets limitKey on the task it builds, or declare the group with a code group type (code.groupTypes) whose create() builds a KeyedRateLimitGroup with a keyFrom that derives the key. A key derived from the flow itself is Q248, deferred`
232
+ });
233
+ }
234
+ return out;
235
+ };
236
+ const check = (flow) => [...validateDefinition(flow, validatorRegistry), ...keyedFindings(flow)];
224
237
  let minted = 0;
225
238
  const inUse = /* @__PURE__ */ new Set();
226
239
  const router = settlementRouter(scheduler);
@@ -237,6 +250,7 @@ function createRuntime(document, code = {}, options = {}) {
237
250
  scheduler,
238
251
  pools: built.derived,
239
252
  groups,
253
+ check,
240
254
  start(flow, payload, startOptions = {}) {
241
255
  return openRun(flow, payload, startOptions, null);
242
256
  },
@@ -252,14 +266,12 @@ function createRuntime(document, code = {}, options = {}) {
252
266
  };
253
267
  return runtime;
254
268
  function openRun(flow, payload, startOptions, from) {
255
- for (const [type, langs] of transformLanguagesByType([flow])) {
256
- if (!resolved.nodeTypes.has(type)) continue;
257
- const carried = builtLanguages.get(type) ?? /* @__PURE__ */ new Set();
258
- for (const lang of langs) {
259
- if (!carried.has(lang)) {
260
- throw new LanguageNotBuilt(type, `flow ${q(flow.flowId)} declares transform.lang ${q(lang)} on a node of type ${q(type)}, and this runtime's pools for that type carry ${carried.size ? [...carried].sort().map(q).join(", ") : "no language"} \u2014 pools are built once, so pass every flow this runtime will run as \`flows\` to createRuntime`);
261
- }
262
- }
269
+ const findings = check(flow);
270
+ const definition = findings.filter((f) => f.rule !== KEYED_RULE);
271
+ if (definition.length) throw InvalidDefinition.fromFindings(flow.flowId, definition);
272
+ const keyed = startOptions.createTask === void 0 ? findings.filter((f) => f.rule === KEYED_RULE) : [];
273
+ if (keyed.length) {
274
+ throw new LimitKeyMissing(keyed[0].at ?? "<document>", `flow "${flow.flowId}" cannot start with no createTask \u2014 ` + keyed.map((f) => `${f.rule} at ${f.at ?? "<document>"}: ${f.detail}`).join("; ") + " (ADR 0097)");
263
275
  }
264
276
  const runId = startOptions.runId ?? mint();
265
277
  if (inUse.has(runId)) {
@@ -275,10 +287,33 @@ function createRuntime(document, code = {}, options = {}) {
275
287
  const settleIfTerminal = () => {
276
288
  if (settled || !isTerminal(state)) return;
277
289
  settled = true;
290
+ if (state.outcome === "interrupted" && stopping.size > 0) {
291
+ const at = state;
292
+ const fin = () => {
293
+ settle(at);
294
+ router.release(runId);
295
+ };
296
+ void Promise.allSettled([...stopping]).then(fin);
297
+ return;
298
+ }
278
299
  settle(state);
279
300
  router.release(runId);
280
301
  };
281
- const scheduler2 = router.forRun(runId);
302
+ const view = router.forRun(runId);
303
+ const stopping = /* @__PURE__ */ new Set();
304
+ const viewCancel = view.cancel;
305
+ const scheduler2 = typeof viewCancel === "function" ? {
306
+ ...view,
307
+ cancel: (id, cancelOptions) => {
308
+ const p = viewCancel(id, cancelOptions);
309
+ stopping.add(p);
310
+ const drop = () => {
311
+ stopping.delete(p);
312
+ };
313
+ p.then(drop, drop);
314
+ return p;
315
+ }
316
+ } : view;
282
317
  const driver = new Driver(flow, {
283
318
  runId,
284
319
  scheduler: scheduler2,
@@ -306,8 +341,13 @@ function createRuntime(document, code = {}, options = {}) {
306
341
  queueMicrotask(settleIfTerminal);
307
342
  startOptions.onFoldInput?.(input, seq);
308
343
  },
344
+ ...startOptions.onHeader !== void 0 ? { onHeader: startOptions.onHeader } : {},
309
345
  ...startOptions.onRegionEvent !== void 0 ? { onRegionEvent: startOptions.onRegionEvent } : {},
310
346
  ...startOptions.onRunFailure !== void 0 ? { onRunFailure: startOptions.onRunFailure } : {},
347
+ // **Spread only when given** (`RN-R42`): the driver subscribes the pass-through events for a callback present, so an
348
+ // `undefined` forwarded here must stay ABSENT — and on a runtime the scheduler is subscribed once the first run asks.
349
+ ...startOptions.onTaskMessage !== void 0 ? { onTaskMessage: startOptions.onTaskMessage } : {},
350
+ ...startOptions.onTaskProgress !== void 0 ? { onTaskProgress: startOptions.onTaskProgress } : {},
311
351
  ...startOptions.onUnsatisfiableJoin !== void 0 ? { onUnsatisfiableJoin: startOptions.onUnsatisfiableJoin } : {},
312
352
  ...startOptions.onUnmintedTask !== void 0 ? { onUnmintedTask: startOptions.onUnmintedTask } : {},
313
353
  ...startOptions.onNonconformingResult !== void 0 ? { onNonconformingResult: startOptions.onNonconformingResult } : {},
@@ -321,7 +361,7 @@ function createRuntime(document, code = {}, options = {}) {
321
361
  router.release(runId);
322
362
  throw e;
323
363
  }
324
- return { driver, done, header: driver.checkpoint().header };
364
+ return { driver, done, header: driver.checkpoint().header, stop: (stopOptions) => driver.stop(stopOptions) };
325
365
  }
326
366
  }
327
367
  function settlementRouter(scheduler) {
@@ -329,7 +369,8 @@ function settlementRouter(scheduler) {
329
369
  const every = /* @__PURE__ */ new Map();
330
370
  const deliver = (name) => (e) => {
331
371
  const detail = "detail" in e ? e.detail : void 0;
332
- const id = typeof detail === "object" && detail !== null ? detail.id : void 0;
372
+ const d = typeof detail === "object" && detail !== null ? detail : void 0;
373
+ const id = typeof d?.id === "string" ? d.id : d?.taskId;
333
374
  let runId = null;
334
375
  if (typeof id === "string") {
335
376
  try {
@@ -355,7 +396,9 @@ function settlementRouter(scheduler) {
355
396
  };
356
397
  return {
357
398
  forRun(runId) {
399
+ const cancel = scheduler.cancel;
358
400
  return {
401
+ ...typeof cancel === "function" ? { cancel: (id, options) => cancel.call(scheduler, id, options) } : {},
359
402
  addTask: (task, options) => scheduler.addTask(task, options),
360
403
  addEventListener(name, listener) {
361
404
  let mine = byRun.get(runId);
@@ -589,7 +632,8 @@ var EnvelopeWorker = class {
589
632
  }
590
633
  }
591
634
  /**
592
- * `FD-C5`: the inner worker receives `{ settings, input }` and nothing else. `FD-C6`: when the
635
+ * `FD-C5`: the inner worker receives `{ settings, input }` as its payload, and the scheduler's task context as its
636
+ * second argument, passed through untouched (W159). `FD-C6`: when the
593
637
  * envelope carries a `transform`, `input` is the evaluation of that expression over the value
594
638
  * received, with the node's settings bound as `$settings`, and the third key is consumed here.
595
639
  */
@@ -613,7 +657,7 @@ var EnvelopeWorker = class {
613
657
  const compile = this.langs.get(t.lang);
614
658
  if (compile === void 0) {
615
659
  const carried = Object.keys(this.cfg.languages ?? {}).map((x) => `"${x}"`).join(", ") || "no languages";
616
- throw new TransformFailed(t, void 0, `language "${t.lang}" is not loaded in this pool (the pool config carries ${carried}) \u2014 the bootstrap helper writes an adapter URL for a type some node of which declares a transform, and needs the flow and the languages to do it`);
660
+ throw new TransformFailed(t, void 0, `language "${t.lang}" is not loaded in this pool (the pool config carries ${carried}) \u2014 the bootstrap helper writes every language it is given into every pool, so this one was not in the registry the pool was built from`);
617
661
  }
618
662
  if (compile instanceof Error) {
619
663
  throw new TransformFailed(t, void 0, `${compile.message} \u2014 every task transforming in "${t.lang}" on this worker fails with this until the pool is rebuilt`);
@@ -654,13 +698,12 @@ export {
654
698
  GROUP_MEMBERS,
655
699
  GroupNotBuildable,
656
700
  GroupUnusable,
657
- LanguageNotBuilt,
701
+ LimitKeyMissing,
658
702
  NotAnEnvelope,
659
703
  RunIdInUse,
660
704
  RuntimeError,
661
705
  TransformFailed,
662
706
  bootstrap,
663
707
  createRuntime,
664
- transformLanguagesByType,
665
708
  unpackEnvelope
666
709
  };
@@ -10,7 +10,7 @@
10
10
  * | | what it answers |
11
11
  * |---|---|
12
12
  * | `pathsOf(schema)` | *what is there to reach for* — every path a value of the schema may carry |
13
- * | `tryTransform(registry, flow, node, transform)` | *does THIS expression fit* — the sample-and-diff loop, one candidate at a time |
13
+ * | `tryTransform(registry, flow, node, transform, { input }?)` | *does THIS expression fit* — the sample-and-diff loop, one candidate at a time, on the arcs' samples or on a value the caller gives |
14
14
  * | `signatureOf(name, worker)` | *what do I write my worker against* — a TypeScript signature from the three schemas |
15
15
  *
16
16
  * **The loop is a SUBSTITUTION over `checkWiring` and not a second evaluator** (W74 fact B): it puts
@@ -19,7 +19,10 @@
19
19
  * branch task composing `"."` and transforming it must be evaluated once per ELEMENT, and an assist
20
20
  * that re-implemented the evaluation would have to rediscover that. Every verdict it returns is
21
21
  * therefore W73's, unchanged: *the sample passed*, never *fits*, with the sample's source and arity
22
- * on it ([Q301](../../doc/questions/q301.md)).
22
+ * on it ([Q301](../../doc/questions/q301.md)). **A given input keeps the substitution** (v0.38,
23
+ * [W166](../../doc/work-items/w166-a-sample-the-caller-gives.md)): the candidate goes on the same copy, and
24
+ * `wiring.ts`'s `givenVerdict` runs it through the same evaluation the arcs take — one verdict, source
25
+ * `'given'`.
23
26
  *
24
27
  * **`pathsOf` does NOT gate on `schemaProblem`, and that is a decision rather than an oversight**
25
28
  * (W74 fact A). ADR 0053 rule 5 puts that gate in front of `findings`, because a VALUE check may not
@@ -91,6 +94,18 @@ export interface CandidateTransform {
91
94
  lang: string;
92
95
  expr: string;
93
96
  }
97
+ /** `tryTransform`'s options: the wiring check's, and the value a caller gives (W166). */
98
+ export interface TryTransformOptions extends WiringOptions {
99
+ /**
100
+ * **What the node RECEIVES — `$` — given by the caller** (v0.38, P37 stop-and-ask (d)): typed or pasted
101
+ * by a person in an editor, or held by an agent. Given, the candidate runs ONCE on this value and
102
+ * `tryTransform` returns ONE verdict of shape `given`, whatever arcs reach the node — the ENTRY node
103
+ * included, which no arc reaches. No `needs` is composed over it: it IS the value the node receives.
104
+ * **`undefined` is not a value** — a key present holding `undefined` is no input, and the arcs answer as
105
+ * they always have (JSON has no `undefined`; `null` IS a value, and is given).
106
+ */
107
+ input?: unknown;
108
+ }
94
109
  /**
95
110
  * **One candidate expression on one node, and what every arc into that node then says** — the
96
111
  * sample-and-diff loop, and the whole of it.
@@ -99,12 +114,21 @@ export interface CandidateTransform {
99
114
  * W73's own: `transform-passes` with the sample's source and arity where every evaluation's result
100
115
  * is accepted by the consumer's `inputSchema`, `transform-fails` with the finding where one is not,
101
116
  * and the transform run once per ELEMENT where the arc is a map's item. Pass `null` to ask what the
102
- * arcs say with NO transform, which is where an author starts.
117
+ * arcs say with NO transform, which is where an author starts — on the ARCS: with a given `input` and
118
+ * `null` there is nothing to run, the one verdict is `unchecked`, and holding that value to the node's
119
+ * `inputSchema` is `findings(schema, value)`'s question (W166's conformity reader, F3).
120
+ *
121
+ * **Given an `input`** (`options.input`, v0.38, [W166](../../doc/work-items/w166-a-sample-the-caller-gives.md)),
122
+ * the candidate goes on the same copy and is run ONCE on that value by `givenVerdict`, the arcs' own
123
+ * evaluation: ONE verdict, shape `given`, NO `producer`, `sample.source: 'given'` — never `'example'` or
124
+ * `'witness'` — the result held to the node's worker `inputSchema` and a compile or evaluation error
125
+ * `transform-fails`, as on an arc. The entry node gets one too. With `null` there is nothing to run the
126
+ * value through, and the one verdict is `unchecked`.
103
127
  *
104
128
  * The flow is never mutated. A node id that names no task returns `[]` — an authoring tool reports,
105
- * and there is nothing to report about a node with no arcs into it.
129
+ * and there is nothing to report about a node with no arcs into it and no input given.
106
130
  */
107
- export declare function tryTransform(registry: WiringRegistry, flow: FlowDefinition, nodeId: string, transform: CandidateTransform | null, options?: WiringOptions): Promise<WiringVerdict[]>;
131
+ export declare function tryTransform(registry: WiringRegistry, flow: FlowDefinition, nodeId: string, transform: CandidateTransform | null, options?: TryTransformOptions): Promise<WiringVerdict[]>;
108
132
  /**
109
133
  * **A schema INFERRED from ONE value** — its TYPE SHAPE in ADR 0053's subset: the types it carries, the
110
134
  * keys it had, and nothing about its values. Evidence about one input and never a declaration, which is
@@ -0,0 +1,49 @@
1
+ /**
2
+ * **A DECLARED condition, evaluated, and the key path it reads** — the pure half of `spec/flow-definition.md`
3
+ * section 3's `when` subsection, in the DEFINITION layer so that both of its readers import it from one place and
4
+ * neither layer imports the other's back: `src/driver/routing.ts`' `evaluateWhen` (a task's or a join's edge) and
5
+ * the built-in `if` gate in `validate.ts` (P32 decision 4: *evaluated by the same evaluator a task edge's `when`
6
+ * is*). [W154](../../doc/work-items/w154-the-built-in-if-and-switch.md) exception (p): until it, the `if` reached
7
+ * the evaluator through `routing.ts`, which imports `src/definition` — a module cycle in a published library.
8
+ *
9
+ * **Not re-exported by `index.ts`.** `readKeyPath` stays public through `validate.ts`' re-export, and
10
+ * `evaluateWhen` through `routing.ts`, so the package's exported names do not move. Nothing here imports anything
11
+ * but types.
12
+ */
13
+ import type { PredicateLeaf, When } from './types.js';
14
+ /**
15
+ * **What a key path NAMES on a value — the meaning of stop-and-ask (d)'s grammar**, one definition for the
16
+ * driver that resolves it (W93, where a branch enters a gate) and the tests that pin it. Each segment is an OWN key of a plain object
17
+ * (`hasOwnProperty`, never `in`, which walks the prototype — W65's conformity reader, three keyword sites);
18
+ * anything else — a missing key, `null`, an ARRAY mid-path (no index, by (d)), a primitive — is
19
+ * `undefined`, which is what `distinct` routes to `nokey`. The value at the end is returned whatever it is.
20
+ */
21
+ export declare function readKeyPath(value: unknown, path: string): unknown;
22
+ /**
23
+ * **A DECLARED comparison, evaluated — v0.27,
24
+ * [ADR 0074](../../doc/decisions/0074-a-predicate-is-a-registered-name-or-a-declared-comparison-over-the-context.md).**
25
+ *
26
+ * **Synchronous, total, and a pure function of its argument** — which is the whole reason the subset
27
+ * exists rather than reusing `transform`'s declared expressions: W108's declaration step re-measured
28
+ * that `jsonata`'s only evaluation entry returns a Promise and that `src/driver/driver.ts` holds ZERO
29
+ * `async`/`await` in code, so an expression cannot be evaluated where a decision is made without
30
+ * reaching [ADR 0014](../../doc/decisions/0014-the-driver-produces-the-folds-ordered-input-sequence.md)'s
31
+ * ordered fold-input sequence.
32
+ *
33
+ * **It reads `scope` and nothing else.** There is no clock here, no random source, no I/O and no
34
+ * closure over anything — so a declared predicate **CANNOT** be impure, which is strictly stronger
35
+ * than [Q9](../../doc/questions/q9.md)'s measured result for a function (evaluating twice caught
36
+ * 1 impurity shape of 4) and is asserted rather than argued. `scope` is a task edge's `DecisionContext`
37
+ * or an `if` gate's `{ input }` (W154) — the path is read off it by `readKeyPath`, and that is the only read.
38
+ *
39
+ * **Total by construction**, because `FD-V42`-`FD-V45` refuse everything this does not handle at
40
+ * `new Driver`. The `default:` arm below is the assertion that they held; `unknownOp` is the error it throws,
41
+ * the caller's own class (`routing.ts` passes `NoMatchingEdge`, as before W154).
42
+ */
43
+ export declare function evalLeaf(scope: object, p: PredicateLeaf, unknownOp: (message: string) => Error): boolean;
44
+ /**
45
+ * **A COMPARISON or a FLAT GROUP, answered** — the two DECLARED shapes of a `when`. A registered NAME is not
46
+ * one: `routing.ts`' `evaluateWhen` looks a name up itself and hands every other shape here, and the `if` gate's
47
+ * grammar refuses a name at load.
48
+ */
49
+ export declare function evaluateDeclared(when: When, scope: object, unknownOp: (message: string) => Error): boolean;