@cartanova/qgrid-cli 2.5.3 → 2.5.5

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.
Files changed (65) hide show
  1. package/README.ko.md +7 -2
  2. package/README.md +7 -2
  3. package/bundle/dist/application/monit/monit.frame.js +3 -3
  4. package/bundle/dist/application/qgrid/oauth.js +1 -1
  5. package/bundle/dist/application/qgrid/qgrid.dispatcher.js +36 -14
  6. package/bundle/dist/application/qgrid/qgrid.frame.js +19 -5
  7. package/bundle/dist/application/qgrid/tool-emulation-schema.js +93 -0
  8. package/bundle/dist/application/qgrid/tool-emulation.js +116 -96
  9. package/bundle/dist/application/request-log/request-log.model.js +3 -3
  10. package/bundle/dist/application/request-log-step/request-log-step.model.js +2 -2
  11. package/bundle/dist/application/token/token.model.js +2 -2
  12. package/bundle/dist/server-error-handler.js +15 -0
  13. package/bundle/dist/sonamu.config.js +4 -7
  14. package/bundle/dist/utils/providers/anthropic/anthropic-dispatcher.js +4 -3
  15. package/bundle/dist/utils/providers/anthropic/claude-session.js +7 -5
  16. package/bundle/dist/utils/providers/common/json-schema-keywords.js +77 -0
  17. package/bundle/dist/utils/providers/common/schema-validation.js +178 -0
  18. package/bundle/dist/utils/providers/common/strictifier.js +332 -42
  19. package/bundle/dist/utils/providers/openai/codex-worker.js +16 -8
  20. package/bundle/dist/utils/providers/openai/openai-dispatcher.js +5 -37
  21. package/bundle/dist/utils/providers/openai/openai-worker-pool-config.js +37 -0
  22. package/bundle/src/application/monit/monit.frame.ts +1 -1
  23. package/bundle/src/application/qgrid/qgrid-run-lifecycle.test.ts +103 -0
  24. package/bundle/src/application/qgrid/qgrid.dispatcher.test.ts +337 -0
  25. package/bundle/src/application/qgrid/qgrid.dispatcher.ts +45 -25
  26. package/bundle/src/application/qgrid/qgrid.frame.test.ts +580 -8
  27. package/bundle/src/application/qgrid/qgrid.frame.ts +28 -1
  28. package/bundle/src/application/qgrid/tool-emulation-schema.test.ts +188 -0
  29. package/bundle/src/application/qgrid/tool-emulation-schema.ts +177 -0
  30. package/bundle/src/application/qgrid/tool-emulation.test.ts +285 -67
  31. package/bundle/src/application/qgrid/tool-emulation.ts +199 -102
  32. package/bundle/src/server-error-handler.ts +22 -0
  33. package/bundle/src/sonamu.config.test.ts +37 -0
  34. package/bundle/src/sonamu.config.ts +2 -5
  35. package/bundle/src/utils/providers/anthropic/anthropic-dispatcher.test.ts +44 -0
  36. package/bundle/src/utils/providers/anthropic/anthropic-dispatcher.ts +2 -2
  37. package/bundle/src/utils/providers/anthropic/claude-session.test.ts +10 -0
  38. package/bundle/src/utils/providers/anthropic/claude-session.ts +6 -1
  39. package/bundle/src/utils/providers/common/json-schema-keywords.ts +72 -0
  40. package/bundle/src/utils/providers/common/schema-validation.test.ts +284 -0
  41. package/bundle/src/utils/providers/common/schema-validation.ts +308 -0
  42. package/bundle/src/utils/providers/common/strictifier.test.ts +746 -0
  43. package/bundle/src/utils/providers/common/strictifier.ts +520 -52
  44. package/bundle/src/utils/providers/openai/codex-worker.test.ts +31 -0
  45. package/bundle/src/utils/providers/openai/codex-worker.ts +12 -4
  46. package/bundle/src/utils/providers/openai/openai-dispatcher.test.ts +6 -4
  47. package/bundle/src/utils/providers/openai/openai-dispatcher.ts +6 -79
  48. package/bundle/src/utils/providers/openai/openai-worker-pool-config.ts +80 -0
  49. package/bundle/web-dist/client/assets/{index-DXdGBfB8.js → index-CN_kMswh.js} +3 -3
  50. package/bundle/web-dist/client/assets/{logs-D_j1yxC4.js → logs-6nYj9OKL.js} +1 -1
  51. package/bundle/web-dist/client/assets/{monit-CIToyoxW.js → monit-CaPH9Uwc.js} +1 -1
  52. package/bundle/web-dist/client/assets/{routes-Dd21A-wi.js → routes-Dh5HPi-b.js} +1 -1
  53. package/bundle/web-dist/client/assets/{show-DfePWRbc.js → show-Be_LVd9d.js} +1 -1
  54. package/bundle/web-dist/client/assets/{tokens-B4MV2fdk.js → tokens-CAi3zu_0.js} +1 -1
  55. package/bundle/web-dist/client/index.html +1 -1
  56. package/bundle/web-dist/server/entry-server.generated.js +1 -1
  57. package/package.json +1 -1
  58. package/skills/qgrid/references/ai-sdk-provider-contract.md +34 -2
  59. package/skills/qgrid/references/anthropic-claude-code-runtime.md +3 -0
  60. package/skills/qgrid/references/cli-env-and-server-boot.md +1 -1
  61. package/skills/qgrid/references/decision-rationale.md +10 -1
  62. package/skills/qgrid/references/docs-workflow.md +9 -0
  63. package/skills/qgrid/references/repo-map.md +2 -1
  64. package/skills/qgrid/references/tool-calling-and-multiturn.md +145 -6
  65. package/skills/qgrid/references/verification-and-debugging.md +16 -1
@@ -0,0 +1,93 @@
1
+ import { SCHEMA_ARRAY_KEYWORDS, SCHEMA_MAP_KEYWORDS, SCHEMA_SINGLE_KEYWORDS, UNSUPPORTED_REFERENCE_KEYWORDS } from "../../utils/providers/common/json-schema-keywords.js";
2
+ //#region src/application/qgrid/tool-emulation-schema.ts
3
+ const USER_OUTPUT_DEFINITION = "__qgrid_user_output";
4
+ const USER_OUTPUT_REF = `#/$defs/${USER_OUTPUT_DEFINITION}`;
5
+ var ToolSchemaCompositionError = class extends Error {
6
+ path;
7
+ constructor(message, path) {
8
+ super(`tool schema composition: ${message} (at ${path})`);
9
+ this.path = path;
10
+ this.name = "ToolSchemaCompositionError";
11
+ }
12
+ };
13
+ function buildToolCallSchema(tools, answerSchema) {
14
+ const toolDescriptions = tools.map((tool) => {
15
+ const schema = JSON.stringify(tool.inputSchema);
16
+ return `- ${tool.name}: ${tool.description ?? ""}\n inputSchema: ${schema}`;
17
+ }).join("\n");
18
+ const normalizedAnswerSchema = answerSchema === void 0 ? void 0 : rebaseUserOutputSchema(answerSchema);
19
+ return {
20
+ type: "object",
21
+ description: "Use this schema only through StructuredOutput. Do not invoke listed client tools as native Claude Code tools. To request client-side tool execution, set action to tool_call and include toolCalls. Use action answer only when no further client tool result is needed.",
22
+ properties: {
23
+ action: {
24
+ type: "string",
25
+ enum: ["answer", "tool_call"],
26
+ description: "Use tool_call to request client-side tool execution through this structured output. Use answer only for a final answer."
27
+ },
28
+ answer: { anyOf: [normalizedAnswerSchema === void 0 ? { type: "string" } : { $ref: USER_OUTPUT_REF }, { type: "null" }] },
29
+ toolCalls: {
30
+ description: "Client-side tool calls requested through structured output. Do not call these tools as native Claude Code tools.",
31
+ anyOf: [{
32
+ type: "array",
33
+ items: {
34
+ type: "object",
35
+ properties: {
36
+ toolName: {
37
+ type: "string",
38
+ enum: tools.map((tool) => tool.name),
39
+ description: `Client-side tool name to request through structured output. Do not call this as a native Claude Code tool.\n${toolDescriptions}`
40
+ },
41
+ args: {
42
+ type: "string",
43
+ description: "Tool arguments as a JSON string for the client-side tool."
44
+ }
45
+ },
46
+ required: ["toolName", "args"],
47
+ additionalProperties: false
48
+ }
49
+ }, { type: "null" }]
50
+ }
51
+ },
52
+ required: [
53
+ "action",
54
+ "answer",
55
+ "toolCalls"
56
+ ],
57
+ additionalProperties: false,
58
+ ...normalizedAnswerSchema === void 0 ? {} : { $defs: { [USER_OUTPUT_DEFINITION]: normalizedAnswerSchema } }
59
+ };
60
+ }
61
+ function rebaseUserOutputSchema(schema) {
62
+ return rewriteSchemaNode(schema, "$");
63
+ }
64
+ const MAP_KEYWORDS = new Set(SCHEMA_MAP_KEYWORDS);
65
+ const ARRAY_KEYWORDS = new Set(SCHEMA_ARRAY_KEYWORDS);
66
+ const SINGLE_KEYWORDS = new Set(SCHEMA_SINGLE_KEYWORDS);
67
+ function rewriteSchemaNode(value, path) {
68
+ if (value === null || typeof value !== "object" || Array.isArray(value)) return value;
69
+ const source = value;
70
+ const result = { ...source };
71
+ for (const unsupportedKeyword of UNSUPPORTED_REFERENCE_KEYWORDS) if (Object.hasOwn(source, unsupportedKeyword)) throw new ToolSchemaCompositionError(`${unsupportedKeyword} is not supported`, `${path}.${unsupportedKeyword}`);
72
+ if ("$ref" in source) {
73
+ const ref = source.$ref;
74
+ if (typeof ref !== "string" || ref !== "#" && !ref.startsWith("#/")) throw new ToolSchemaCompositionError("only root-relative JSON Pointer $ref values are supported", `${path}.$ref`);
75
+ result.$ref = `${USER_OUTPUT_REF}${ref.slice(1)}`;
76
+ }
77
+ for (const [keyword, child] of Object.entries(source)) {
78
+ const keywordPath = `${path}.${keyword}`;
79
+ if (MAP_KEYWORDS.has(keyword) && isJsonObject(child)) result[keyword] = Object.fromEntries(Object.entries(child).map(([name, schema]) => [name, rewriteSchemaNode(schema, `${keywordPath}.${name}`)]));
80
+ else if (keyword === "dependencies" && isJsonObject(child)) result[keyword] = Object.fromEntries(Object.entries(child).map(([name, dependency]) => [name, Array.isArray(dependency) ? dependency : rewriteSchemaNode(dependency, `${keywordPath}.${name}`)]));
81
+ else if (ARRAY_KEYWORDS.has(keyword) && Array.isArray(child)) result[keyword] = child.map((schema, index) => rewriteSchemaNode(schema, `${keywordPath}[${index}]`));
82
+ else if (SINGLE_KEYWORDS.has(keyword)) if (keyword === "items" && Array.isArray(child)) result[keyword] = child.map((schema, index) => rewriteSchemaNode(schema, `${keywordPath}[${index}]`));
83
+ else result[keyword] = rewriteSchemaNode(child, keywordPath);
84
+ }
85
+ return result;
86
+ }
87
+ function isJsonObject(value) {
88
+ return value !== null && typeof value === "object" && !Array.isArray(value);
89
+ }
90
+ //#endregion
91
+ export { ToolSchemaCompositionError, buildToolCallSchema };
92
+
93
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG9vbC1lbXVsYXRpb24tc2NoZW1hLmpzIiwibmFtZXMiOltdLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9hcHBsaWNhdGlvbi9xZ3JpZC90b29sLWVtdWxhdGlvbi1zY2hlbWEudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiB0b29sIGVudmVsb3BlICsg7IKs7Jqp7J6QIG91dHB1dCDsiqTtgqTrp4gg7ZWp7ISxICjsmpTssq0g67Cp7ZalKS4g7J2R64u1IO2VtOyEneydgCB0b29sLWVtdWxhdGlvbi50cy5cbiAqXG4gKiB0b29scyDqsIAg7J6I7Ja064+EIOy1nOyihSBhbnN3ZXIg6rCAIOyCrOyaqeyekCDsiqTtgqTrp4jroZwg6rCV7KCc65CY6rKMIO2VmOugpOqzoCBlbnZlbG9wZSDsnZggYW5zd2VyIOu4jOuenOy5mOyXkFxuICog7IKs7Jqp7J6QIOyKpO2CpOuniOulvCDsi6zripTri6QuIO2GteynuOuhnCDspJHssqntlaAg7IiYIOyXhuuKlCDsnbTsnKDripQgYCRyZWZgIOqwgCDrrLjshJwg7KCI64yAIOqyveuhnOydtOq4sCDrlYzrrLgg4oCUXG4gKiBgI2Ag7J2AIFwi7J20IOyhsOqwgeydmCDro6jtirhcIuqwgCDslYTri4jrnbwgXCLstZzsooUg66y47ISc7J2YIOujqO2KuFwi6528LCDqt7jrjIDroZwg64Sj7Jy866m0IO2PrOyduO2EsOqwgCBlbnZlbG9wZSDsnYRcbiAqIOqwgOumrOy8nCDsobDsmqntnogg7JeJ65qx7ZWcIOqxuCDqsoDspp3tlZjqsowg65Cc64ukLiDqt7jrnpjshJwg7JiI7JW9IOydtOumhCDslYTrnpjroZwg7Jiu6riw6rOgIOuhnOy7rCDtj6zsnbjthLDrpbwg7J6s7J6R7ISx7ZWc64ukLlxuICpcbiAqIOuwsOqyvcK37Iuk7LihwrfsmIjsi5zCt+qxsOu2gCDrqqnroZ3snYAg7Iqk7YKsIOusuOyEnOulvCDrs7wg6rKDOlxuICogICBwYWNrYWdlcy9jbGkvc2tpbGxzL3FncmlkL3JlZmVyZW5jZXMvdG9vbC1jYWxsaW5nLWFuZC1tdWx0aXR1cm4ubWRcbiAqICAg4oaSIFwiQ29tcG9zaW5nIFRvb2xzIFdpdGggQSBVc2VyIE91dHB1dCBTY2hlbWFcIlxuICovXG5cbmltcG9ydCB7IHR5cGUgSnNvblZhbHVlIH0gZnJvbSBcIi4uLy4uL2NvZGV4LXByb3RvY29sL3NlcmRlX2pzb24vSnNvblZhbHVlXCI7XG5pbXBvcnQge1xuICBTQ0hFTUFfQVJSQVlfS0VZV09SRFMsXG4gIFNDSEVNQV9ERVBFTkRFTkNJRVNfS0VZV09SRCxcbiAgU0NIRU1BX01BUF9LRVlXT1JEUyxcbiAgU0NIRU1BX1NJTkdMRV9LRVlXT1JEUyxcbiAgVU5TVVBQT1JURURfUkVGRVJFTkNFX0tFWVdPUkRTLFxufSBmcm9tIFwiLi4vLi4vdXRpbHMvcHJvdmlkZXJzL2NvbW1vbi9qc29uLXNjaGVtYS1rZXl3b3Jkc1wiO1xuaW1wb3J0IHsgdHlwZSBRZ3JpZFRvb2wgfSBmcm9tIFwiLi9xZ3JpZC50eXBlc1wiO1xuXG5jb25zdCBVU0VSX09VVFBVVF9ERUZJTklUSU9OID0gXCJfX3FncmlkX3VzZXJfb3V0cHV0XCI7XG5jb25zdCBVU0VSX09VVFBVVF9SRUYgPSBgIy8kZGVmcy8ke1VTRVJfT1VUUFVUX0RFRklOSVRJT059YDtcblxuZXhwb3J0IGNsYXNzIFRvb2xTY2hlbWFDb21wb3NpdGlvbkVycm9yIGV4dGVuZHMgRXJyb3Ige1xuICBjb25zdHJ1Y3RvcihcbiAgICBtZXNzYWdlOiBzdHJpbmcsXG4gICAgcHVibGljIHBhdGg6IHN0cmluZyxcbiAgKSB7XG4gICAgc3VwZXIoYHRvb2wgc2NoZW1hIGNvbXBvc2l0aW9uOiAke21lc3NhZ2V9IChhdCAke3BhdGh9KWApO1xuICAgIHRoaXMubmFtZSA9IFwiVG9vbFNjaGVtYUNvbXBvc2l0aW9uRXJyb3JcIjtcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gYnVpbGRUb29sQ2FsbFNjaGVtYSh0b29sczogUWdyaWRUb29sW10sIGFuc3dlclNjaGVtYT86IEpzb25WYWx1ZSk6IEpzb25WYWx1ZSB7XG4gIGNvbnN0IHRvb2xEZXNjcmlwdGlvbnMgPSB0b29sc1xuICAgIC5tYXAoKHRvb2wpID0+IHtcbiAgICAgIGNvbnN0IHNjaGVtYSA9IEpTT04uc3RyaW5naWZ5KHRvb2wuaW5wdXRTY2hlbWEpO1xuICAgICAgcmV0dXJuIGAtICR7dG9vbC5uYW1lfTogJHt0b29sLmRlc2NyaXB0aW9uID8/IFwiXCJ9XFxuICBpbnB1dFNjaGVtYTogJHtzY2hlbWF9YDtcbiAgICB9KVxuICAgIC5qb2luKFwiXFxuXCIpO1xuXG4gIGNvbnN0IG5vcm1hbGl6ZWRBbnN3ZXJTY2hlbWEgPVxuICAgIGFuc3dlclNjaGVtYSA9PT0gdW5kZWZpbmVkID8gdW5kZWZpbmVkIDogcmViYXNlVXNlck91dHB1dFNjaGVtYShhbnN3ZXJTY2hlbWEpO1xuXG4gIHJldHVybiB7XG4gICAgdHlwZTogXCJvYmplY3RcIixcbiAgICBkZXNjcmlwdGlvbjpcbiAgICAgIFwiVXNlIHRoaXMgc2NoZW1hIG9ubHkgdGhyb3VnaCBTdHJ1Y3R1cmVkT3V0cHV0LiBEbyBub3QgaW52b2tlIGxpc3RlZCBjbGllbnQgdG9vbHMgYXMgbmF0aXZlIENsYXVkZSBDb2RlIHRvb2xzLiBUbyByZXF1ZXN0IGNsaWVudC1zaWRlIHRvb2wgZXhlY3V0aW9uLCBzZXQgYWN0aW9uIHRvIHRvb2xfY2FsbCBhbmQgaW5jbHVkZSB0b29sQ2FsbHMuIFVzZSBhY3Rpb24gYW5zd2VyIG9ubHkgd2hlbiBubyBmdXJ0aGVyIGNsaWVudCB0b29sIHJlc3VsdCBpcyBuZWVkZWQuXCIsXG4gICAgcHJvcGVydGllczoge1xuICAgICAgYWN0aW9uOiB7XG4gICAgICAgIHR5cGU6IFwic3RyaW5nXCIsXG4gICAgICAgIGVudW06IFtcImFuc3dlclwiLCBcInRvb2xfY2FsbFwiXSxcbiAgICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICAgXCJVc2UgdG9vbF9jYWxsIHRvIHJlcXVlc3QgY2xpZW50LXNpZGUgdG9vbCBleGVjdXRpb24gdGhyb3VnaCB0aGlzIHN0cnVjdHVyZWQgb3V0cHV0LiBVc2UgYW5zd2VyIG9ubHkgZm9yIGEgZmluYWwgYW5zd2VyLlwiLFxuICAgICAgfSxcbiAgICAgIGFuc3dlcjoge1xuICAgICAgICBhbnlPZjogW1xuICAgICAgICAgIG5vcm1hbGl6ZWRBbnN3ZXJTY2hlbWEgPT09IHVuZGVmaW5lZCA/IHsgdHlwZTogXCJzdHJpbmdcIiB9IDogeyAkcmVmOiBVU0VSX09VVFBVVF9SRUYgfSxcbiAgICAgICAgICB7IHR5cGU6IFwibnVsbFwiIH0sXG4gICAgICAgIF0sXG4gICAgICB9LFxuICAgICAgdG9vbENhbGxzOiB7XG4gICAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAgIFwiQ2xpZW50LXNpZGUgdG9vbCBjYWxscyByZXF1ZXN0ZWQgdGhyb3VnaCBzdHJ1Y3R1cmVkIG91dHB1dC4gRG8gbm90IGNhbGwgdGhlc2UgdG9vbHMgYXMgbmF0aXZlIENsYXVkZSBDb2RlIHRvb2xzLlwiLFxuICAgICAgICBhbnlPZjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIHR5cGU6IFwiYXJyYXlcIixcbiAgICAgICAgICAgIGl0ZW1zOiB7XG4gICAgICAgICAgICAgIHR5cGU6IFwib2JqZWN0XCIsXG4gICAgICAgICAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgICAgICAgICB0b29sTmFtZToge1xuICAgICAgICAgICAgICAgICAgdHlwZTogXCJzdHJpbmdcIixcbiAgICAgICAgICAgICAgICAgIGVudW06IHRvb2xzLm1hcCgodG9vbCkgPT4gdG9vbC5uYW1lKSxcbiAgICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBgQ2xpZW50LXNpZGUgdG9vbCBuYW1lIHRvIHJlcXVlc3QgdGhyb3VnaCBzdHJ1Y3R1cmVkIG91dHB1dC4gRG8gbm90IGNhbGwgdGhpcyBhcyBhIG5hdGl2ZSBDbGF1ZGUgQ29kZSB0b29sLlxcbiR7dG9vbERlc2NyaXB0aW9uc31gLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgYXJnczoge1xuICAgICAgICAgICAgICAgICAgdHlwZTogXCJzdHJpbmdcIixcbiAgICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBcIlRvb2wgYXJndW1lbnRzIGFzIGEgSlNPTiBzdHJpbmcgZm9yIHRoZSBjbGllbnQtc2lkZSB0b29sLlwiLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHJlcXVpcmVkOiBbXCJ0b29sTmFtZVwiLCBcImFyZ3NcIl0sXG4gICAgICAgICAgICAgIGFkZGl0aW9uYWxQcm9wZXJ0aWVzOiBmYWxzZSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7IHR5cGU6IFwibnVsbFwiIH0sXG4gICAgICAgIF0sXG4gICAgICB9LFxuICAgIH0sXG4gICAgcmVxdWlyZWQ6IFtcImFjdGlvblwiLCBcImFuc3dlclwiLCBcInRvb2xDYWxsc1wiXSxcbiAgICBhZGRpdGlvbmFsUHJvcGVydGllczogZmFsc2UsXG4gICAgLi4uKG5vcm1hbGl6ZWRBbnN3ZXJTY2hlbWEgPT09IHVuZGVmaW5lZFxuICAgICAgPyB7fVxuICAgICAgOiB7XG4gICAgICAgICAgJGRlZnM6IHtcbiAgICAgICAgICAgIFtVU0VSX09VVFBVVF9ERUZJTklUSU9OXTogbm9ybWFsaXplZEFuc3dlclNjaGVtYSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KSxcbiAgfTtcbn1cblxuZnVuY3Rpb24gcmViYXNlVXNlck91dHB1dFNjaGVtYShzY2hlbWE6IEpzb25WYWx1ZSk6IEpzb25WYWx1ZSB7XG4gIHJldHVybiByZXdyaXRlU2NoZW1hTm9kZShzY2hlbWEsIFwiJFwiKTtcbn1cblxuY29uc3QgTUFQX0tFWVdPUkRTID0gbmV3IFNldDxzdHJpbmc+KFNDSEVNQV9NQVBfS0VZV09SRFMpO1xuY29uc3QgQVJSQVlfS0VZV09SRFMgPSBuZXcgU2V0PHN0cmluZz4oU0NIRU1BX0FSUkFZX0tFWVdPUkRTKTtcbmNvbnN0IFNJTkdMRV9LRVlXT1JEUyA9IG5ldyBTZXQ8c3RyaW5nPihTQ0hFTUFfU0lOR0xFX0tFWVdPUkRTKTtcblxuZnVuY3Rpb24gcmV3cml0ZVNjaGVtYU5vZGUodmFsdWU6IEpzb25WYWx1ZSwgcGF0aDogc3RyaW5nKTogSnNvblZhbHVlIHtcbiAgaWYgKHZhbHVlID09PSBudWxsIHx8IHR5cGVvZiB2YWx1ZSAhPT0gXCJvYmplY3RcIiB8fCBBcnJheS5pc0FycmF5KHZhbHVlKSkgcmV0dXJuIHZhbHVlO1xuXG4gIGNvbnN0IHNvdXJjZSA9IHZhbHVlIGFzIFJlY29yZDxzdHJpbmcsIEpzb25WYWx1ZT47XG4gIGNvbnN0IHJlc3VsdDogUmVjb3JkPHN0cmluZywgSnNvblZhbHVlPiA9IHsgLi4uc291cmNlIH07XG5cbiAgZm9yIChjb25zdCB1bnN1cHBvcnRlZEtleXdvcmQgb2YgVU5TVVBQT1JURURfUkVGRVJFTkNFX0tFWVdPUkRTKSB7XG4gICAgaWYgKE9iamVjdC5oYXNPd24oc291cmNlLCB1bnN1cHBvcnRlZEtleXdvcmQpKSB7XG4gICAgICB0aHJvdyBuZXcgVG9vbFNjaGVtYUNvbXBvc2l0aW9uRXJyb3IoXG4gICAgICAgIGAke3Vuc3VwcG9ydGVkS2V5d29yZH0gaXMgbm90IHN1cHBvcnRlZGAsXG4gICAgICAgIGAke3BhdGh9LiR7dW5zdXBwb3J0ZWRLZXl3b3JkfWAsXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIGlmIChcIiRyZWZcIiBpbiBzb3VyY2UpIHtcbiAgICBjb25zdCByZWYgPSBzb3VyY2UuJHJlZjtcbiAgICBpZiAodHlwZW9mIHJlZiAhPT0gXCJzdHJpbmdcIiB8fCAocmVmICE9PSBcIiNcIiAmJiAhcmVmLnN0YXJ0c1dpdGgoXCIjL1wiKSkpIHtcbiAgICAgIHRocm93IG5ldyBUb29sU2NoZW1hQ29tcG9zaXRpb25FcnJvcihcbiAgICAgICAgXCJvbmx5IHJvb3QtcmVsYXRpdmUgSlNPTiBQb2ludGVyICRyZWYgdmFsdWVzIGFyZSBzdXBwb3J0ZWRcIixcbiAgICAgICAgYCR7cGF0aH0uJHJlZmAsXG4gICAgICApO1xuICAgIH1cbiAgICByZXN1bHQuJHJlZiA9IGAke1VTRVJfT1VUUFVUX1JFRn0ke3JlZi5zbGljZSgxKX1gO1xuICB9XG5cbiAgZm9yIChjb25zdCBba2V5d29yZCwgY2hpbGRdIG9mIE9iamVjdC5lbnRyaWVzKHNvdXJjZSkpIHtcbiAgICBjb25zdCBrZXl3b3JkUGF0aCA9IGAke3BhdGh9LiR7a2V5d29yZH1gO1xuXG4gICAgaWYgKE1BUF9LRVlXT1JEUy5oYXMoa2V5d29yZCkgJiYgaXNKc29uT2JqZWN0KGNoaWxkKSkge1xuICAgICAgcmVzdWx0W2tleXdvcmRdID0gT2JqZWN0LmZyb21FbnRyaWVzKFxuICAgICAgICBPYmplY3QuZW50cmllcyhjaGlsZCkubWFwKChbbmFtZSwgc2NoZW1hXSkgPT4gW1xuICAgICAgICAgIG5hbWUsXG4gICAgICAgICAgcmV3cml0ZVNjaGVtYU5vZGUoc2NoZW1hLCBgJHtrZXl3b3JkUGF0aH0uJHtuYW1lfWApLFxuICAgICAgICBdKSxcbiAgICAgICkgYXMgSnNvblZhbHVlO1xuICAgIH0gZWxzZSBpZiAoa2V5d29yZCA9PT0gU0NIRU1BX0RFUEVOREVOQ0lFU19LRVlXT1JEICYmIGlzSnNvbk9iamVjdChjaGlsZCkpIHtcbiAgICAgIHJlc3VsdFtrZXl3b3JkXSA9IE9iamVjdC5mcm9tRW50cmllcyhcbiAgICAgICAgT2JqZWN0LmVudHJpZXMoY2hpbGQpLm1hcCgoW25hbWUsIGRlcGVuZGVuY3ldKSA9PiBbXG4gICAgICAgICAgbmFtZSxcbiAgICAgICAgICBBcnJheS5pc0FycmF5KGRlcGVuZGVuY3kpXG4gICAgICAgICAgICA/IGRlcGVuZGVuY3lcbiAgICAgICAgICAgIDogcmV3cml0ZVNjaGVtYU5vZGUoZGVwZW5kZW5jeSwgYCR7a2V5d29yZFBhdGh9LiR7bmFtZX1gKSxcbiAgICAgICAgXSksXG4gICAgICApIGFzIEpzb25WYWx1ZTtcbiAgICB9IGVsc2UgaWYgKEFSUkFZX0tFWVdPUkRTLmhhcyhrZXl3b3JkKSAmJiBBcnJheS5pc0FycmF5KGNoaWxkKSkge1xuICAgICAgcmVzdWx0W2tleXdvcmRdID0gY2hpbGQubWFwKChzY2hlbWEsIGluZGV4KSA9PlxuICAgICAgICByZXdyaXRlU2NoZW1hTm9kZShzY2hlbWEsIGAke2tleXdvcmRQYXRofVske2luZGV4fV1gKSxcbiAgICAgICkgYXMgSnNvblZhbHVlO1xuICAgIH0gZWxzZSBpZiAoU0lOR0xFX0tFWVdPUkRTLmhhcyhrZXl3b3JkKSkge1xuICAgICAgaWYgKGtleXdvcmQgPT09IFwiaXRlbXNcIiAmJiBBcnJheS5pc0FycmF5KGNoaWxkKSkge1xuICAgICAgICByZXN1bHRba2V5d29yZF0gPSBjaGlsZC5tYXAoKHNjaGVtYSwgaW5kZXgpID0+XG4gICAgICAgICAgcmV3cml0ZVNjaGVtYU5vZGUoc2NoZW1hLCBgJHtrZXl3b3JkUGF0aH1bJHtpbmRleH1dYCksXG4gICAgICAgICkgYXMgSnNvblZhbHVlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVzdWx0W2tleXdvcmRdID0gcmV3cml0ZVNjaGVtYU5vZGUoY2hpbGQsIGtleXdvcmRQYXRoKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gcmVzdWx0IGFzIEpzb25WYWx1ZTtcbn1cblxuZnVuY3Rpb24gaXNKc29uT2JqZWN0KHZhbHVlOiBKc29uVmFsdWUpOiB2YWx1ZSBpcyBSZWNvcmQ8c3RyaW5nLCBKc29uVmFsdWU+IHtcbiAgcmV0dXJuIHZhbHVlICE9PSBudWxsICYmIHR5cGVvZiB2YWx1ZSA9PT0gXCJvYmplY3RcIiAmJiAhQXJyYXkuaXNBcnJheSh2YWx1ZSk7XG59XG4iXSwibWFwcGluZ3MiOiI7O0FBdUJBLE1BQU0seUJBQXlCO0FBQy9CLE1BQU0sa0JBQWtCLFdBQVc7QUFFbkMsSUFBYSw2QkFBYixjQUFnRCxNQUFNO0NBRzNDO0NBRlQsWUFDRSxTQUNBLE1BQ0E7RUFDQSxNQUFNLDRCQUE0QixRQUFRLE9BQU8sS0FBSyxFQUFFO0VBRmpELEtBQUEsT0FBQTtFQUdQLEtBQUssT0FBTztDQUNkO0FB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
@@ -1,107 +1,95 @@
1
+ import { Buffer } from "node:buffer";
2
+ import { z } from "zod";
1
3
  import { getLogger } from "@logtape/logtape";
2
4
  //#region src/application/qgrid/tool-emulation.ts
5
+ const STRUCTURED_ENVELOPE_LIMITS = {
6
+ maxUtf8Bytes: 512 * 1024,
7
+ maxNodes: 2e4,
8
+ maxDepth: 132
9
+ };
3
10
  const logger = getLogger(["qgrid", "tool-emulation"]);
4
- function appendImages(content, images) {
5
- if (!images?.length) return content;
6
- return [...content, ...images.map((img) => ({
7
- type: "image",
8
- data: img.data,
9
- revisedPrompt: img.revisedPrompt ?? null
10
- }))];
11
- }
12
- function buildToolCallSchema(tools) {
13
- const toolDescriptions = tools.map((tool) => {
14
- const schema = JSON.stringify(tool.inputSchema);
15
- return `- ${tool.name}: ${tool.description ?? ""}\n inputSchema: ${schema}`;
16
- }).join("\n");
17
- return {
18
- type: "object",
19
- description: "Use this schema only through StructuredOutput. Do not invoke listed client tools as native Claude Code tools. To request client-side tool execution, set action to tool_call and include toolCalls. Use action answer only when no further client tool result is needed.",
20
- properties: {
21
- action: {
22
- type: "string",
23
- enum: ["answer", "tool_call"],
24
- description: "Use tool_call to request client-side tool execution through this structured output. Use answer only for a final answer."
25
- },
26
- answer: { anyOf: [{ type: "string" }, { type: "null" }] },
27
- toolCalls: {
28
- description: "Client-side tool calls requested through structured output. Do not call these tools as native Claude Code tools.",
29
- anyOf: [{
30
- type: "array",
31
- items: {
32
- type: "object",
33
- properties: {
34
- toolName: {
35
- type: "string",
36
- enum: tools.map((tool) => tool.name),
37
- description: `Client-side tool name to request through structured output. Do not call this as a native Claude Code tool.\n${toolDescriptions}`
38
- },
39
- args: {
40
- type: "string",
41
- description: "Tool arguments as a JSON string for the client-side tool."
42
- }
43
- },
44
- required: ["toolName", "args"],
45
- additionalProperties: false
46
- }
47
- }, { type: "null" }]
48
- }
49
- },
50
- required: [
51
- "action",
52
- "answer",
53
- "toolCalls"
54
- ],
55
- additionalProperties: false
56
- };
57
- }
58
- function applyToolCallEmulation(result, tools, threadCoord, images) {
59
- const runContext = threadCoord ? { threadCoord } : void 0;
60
- if (!tools?.length) {
61
- const content = [{
62
- type: "text",
63
- text: result.text
64
- }];
65
- return {
66
- ...result,
67
- content: appendImages(content, images),
68
- finishReason: "stop",
69
- runContext
70
- };
11
+ const StructuredToolCallResponse = z.discriminatedUnion("action", [z.strictObject({
12
+ action: z.literal("answer"),
13
+ answer: z.json().refine((answer) => answer !== null, { message: "answer must be non-null" }),
14
+ toolCalls: z.union([z.null(), z.tuple([])])
15
+ }), z.strictObject({
16
+ action: z.literal("tool_call"),
17
+ answer: z.null(),
18
+ toolCalls: z.array(z.strictObject({
19
+ toolName: z.string(),
20
+ args: z.string()
21
+ })).min(1)
22
+ })]);
23
+ var ToolCallEmulationError = class extends Error {
24
+ constructor(message) {
25
+ super(`tool-call emulation: ${message}`);
26
+ this.name = "ToolCallEmulationError";
71
27
  }
28
+ };
29
+ function applyToolCallEmulation(result, tools, options = {}) {
30
+ const { threadCoord, images, answerMode = "legacy" } = options;
31
+ const runContext = threadCoord ? { threadCoord } : void 0;
32
+ if (!tools?.length) return answerOutput(result, result.text, images, runContext);
33
+ if (answerMode === "legacy") return applyLegacyResponse(result, tools, images, runContext);
34
+ const parsed = parseStructuredResponse(result.text, tools);
35
+ if (parsed.action === "tool_call") return toolCallOutput(result, parsed.toolCalls, images, runContext);
36
+ return answerOutput(result, JSON.stringify(parsed.answer), images, runContext);
37
+ }
38
+ /**
39
+ * Tools-only requests keep the permissive 2.5.3 contract. Structured-output requests use the
40
+ * strict decoder below because their outer action envelope is an internal server contract.
41
+ */
42
+ function applyLegacyResponse(result, tools, images, runContext) {
72
43
  let parsed;
73
44
  try {
74
45
  parsed = JSON.parse(result.text);
75
- } catch (e) {
76
- logger.warn(`tool-call emulation parse failed, falling back to text: ${e.message}`);
77
- return {
78
- ...result,
79
- content: appendImages([{
80
- type: "text",
81
- text: result.text
82
- }], images),
83
- finishReason: "stop",
84
- runContext
85
- };
46
+ } catch (error) {
47
+ logger.warn(`tool-call emulation parse failed, falling back to text: ${error.message}`);
48
+ return answerOutput(result, result.text, images, runContext);
86
49
  }
87
50
  if (parsed.action === "tool_call") {
88
- const content = (parsed.toolCalls ?? []).map((toolCall) => {
89
- if (!tools.some((tool) => tool.name === toolCall.toolName)) throw new Error(`unknown emulated tool: ${toolCall.toolName}`);
90
- return {
91
- type: "tool-call",
92
- toolCallId: `call_${Math.random().toString(36).slice(2, 10)}`,
93
- toolName: toolCall.toolName,
94
- input: toolCall.args
95
- };
96
- });
97
- return {
98
- ...result,
99
- content: appendImages(content, images),
100
- finishReason: "tool-calls",
101
- runContext
102
- };
51
+ const toolCalls = parsed.toolCalls ?? [];
52
+ const unknownTool = findUnknownTool(toolCalls, tools);
53
+ if (unknownTool !== void 0) throw new Error(`unknown emulated tool: ${unknownTool}`);
54
+ return toolCallOutput(result, toolCalls, images, runContext);
55
+ }
56
+ return answerOutput(result, parsed.answer ?? result.text, images, runContext);
57
+ }
58
+ function parseStructuredResponse(text, tools) {
59
+ if (Buffer.byteLength(text, "utf8") > STRUCTURED_ENVELOPE_LIMITS.maxUtf8Bytes) throw new ToolCallEmulationError(`structured-output envelope exceeds UTF-8 byte limit of ${STRUCTURED_ENVELOPE_LIMITS.maxUtf8Bytes}`);
60
+ let value;
61
+ try {
62
+ value = JSON.parse(text);
63
+ } catch (error) {
64
+ throw new ToolCallEmulationError(`invalid structured-output envelope: ${error.message}`);
65
+ }
66
+ assertStructuredEnvelopeComplexity(value);
67
+ const validation = StructuredToolCallResponse.safeParse(value);
68
+ if (!validation.success) {
69
+ const issue = validation.error.issues[0];
70
+ throw new ToolCallEmulationError(`invalid structured-output envelope${issue && issue.path.length > 0 ? ` at ${issue.path.join(".")}` : ""}: ${issue?.message ?? "unknown validation issue"}`);
103
71
  }
104
- const text = parsed.answer ?? result.text;
72
+ const response = value;
73
+ if (response.action === "tool_call") {
74
+ const unknownTool = findUnknownTool(response.toolCalls, tools);
75
+ if (unknownTool !== void 0) throw new ToolCallEmulationError(`unknown emulated tool: ${unknownTool}`);
76
+ }
77
+ return response;
78
+ }
79
+ function toolCallOutput(result, toolCalls, images, runContext) {
80
+ return {
81
+ ...result,
82
+ content: appendImages(toolCalls.map((toolCall) => ({
83
+ type: "tool-call",
84
+ toolCallId: `call_${Math.random().toString(36).slice(2, 10)}`,
85
+ toolName: toolCall.toolName,
86
+ input: toolCall.args
87
+ })), images),
88
+ finishReason: "tool-calls",
89
+ runContext
90
+ };
91
+ }
92
+ function answerOutput(result, text, images, runContext) {
105
93
  return {
106
94
  ...result,
107
95
  text,
@@ -113,7 +101,39 @@ function applyToolCallEmulation(result, tools, threadCoord, images) {
113
101
  runContext
114
102
  };
115
103
  }
104
+ function findUnknownTool(toolCalls, tools) {
105
+ const knownToolNames = new Set(tools.map((tool) => tool.name));
106
+ return toolCalls.find((toolCall) => !knownToolNames.has(toolCall.toolName))?.toolName;
107
+ }
108
+ function appendImages(content, images) {
109
+ if (!images?.length) return content;
110
+ return [...content, ...images.map((image) => ({
111
+ type: "image",
112
+ data: image.data,
113
+ revisedPrompt: image.revisedPrompt ?? null
114
+ }))];
115
+ }
116
+ function assertStructuredEnvelopeComplexity(root) {
117
+ const maxDepth = STRUCTURED_ENVELOPE_LIMITS.maxDepth;
118
+ const stack = [{
119
+ value: root,
120
+ depth: 0
121
+ }];
122
+ let nodes = 0;
123
+ while (stack.length > 0) {
124
+ const current = stack.pop();
125
+ nodes += 1;
126
+ if (nodes > STRUCTURED_ENVELOPE_LIMITS.maxNodes) throw new ToolCallEmulationError(`structured-output envelope exceeds node limit of ${STRUCTURED_ENVELOPE_LIMITS.maxNodes}`);
127
+ if (current.depth > maxDepth) throw new ToolCallEmulationError(`structured-output envelope exceeds depth limit of ${maxDepth}`);
128
+ if (typeof current.value === "number" && !Number.isFinite(current.value)) throw new ToolCallEmulationError("answer must be valid JSON");
129
+ if (current.value === null || typeof current.value !== "object") continue;
130
+ for (const value of Object.values(current.value)) stack.push({
131
+ value,
132
+ depth: current.depth + 1
133
+ });
134
+ }
135
+ }
116
136
  //#endregion
117
- export { applyToolCallEmulation, buildToolCallSchema };
137
+ export { ToolCallEmulationError, applyToolCallEmulation };
118
138
 
119
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG9vbC1lbXVsYXRpb24uanMiLCJuYW1lcyI6W10sInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2FwcGxpY2F0aW9uL3FncmlkL3Rvb2wtZW11bGF0aW9uLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGdldExvZ2dlciB9IGZyb20gXCJAbG9ndGFwZS9sb2d0YXBlXCI7XG5cbmltcG9ydCB7IHR5cGUgSnNvblZhbHVlIH0gZnJvbSBcIi4uLy4uL2NvZGV4LXByb3RvY29sL3NlcmRlX2pzb24vSnNvblZhbHVlXCI7XG5pbXBvcnQge1xuICB0eXBlIFFncmlkQ29udGVudCxcbiAgdHlwZSBRZ3JpZFRocmVhZENvb3JkLFxuICB0eXBlIFFncmlkVG9vbCxcbiAgdHlwZSBRdWVyeU91dHB1dCxcbn0gZnJvbSBcIi4vcWdyaWQudHlwZXNcIjtcblxuY29uc3QgbG9nZ2VyID0gZ2V0TG9nZ2VyKFtcInFncmlkXCIsIFwidG9vbC1lbXVsYXRpb25cIl0pO1xuXG50eXBlIFRvb2xDYWxsUmVzcG9uc2UgPSB7XG4gIGFjdGlvbjogXCJhbnN3ZXJcIiB8IFwidG9vbF9jYWxsXCI7XG4gIGFuc3dlcj86IHN0cmluZyB8IG51bGw7XG4gIHRvb2xDYWxscz86IEFycmF5PHsgdG9vbE5hbWU6IHN0cmluZzsgYXJnczogc3RyaW5nIH0+IHwgbnVsbDtcbn07XG5cbi8vIGRpc3BhdGNoZXIg6rCAIOuEmOq4sOuKlCDsnbTrr7jsp4Ag6rKw6rO8LiBxZ3JpZCDripQgYmFzZTY0IHBheWxvYWQg66eMIOyghOuLrO2VmOqzoCDtj6zrp7fsnYAg67O07J6l7ZWY7KeAIOyViuuKlOuLpC5cbmV4cG9ydCBpbnRlcmZhY2UgRW11bGF0aW9uSW1hZ2Uge1xuICBkYXRhOiBzdHJpbmc7XG4gIHJldmlzZWRQcm9tcHQ/OiBzdHJpbmcgfCBudWxsO1xufVxuXG4vLyDsobDrpr3rkJwgY29udGVudCDrkqTsl5Ag7J2066+47KeAIO2MjO2KuOulvCBhcHBlbmQg7ZWc64ukLiDrqqjrk6Ag67CY7ZmYIOu2hOq4sOqwgCDqs7XsnKAuXG5mdW5jdGlvbiBhcHBlbmRJbWFnZXMoY29udGVudDogUWdyaWRDb250ZW50W10sIGltYWdlcz86IEVtdWxhdGlvbkltYWdlW10pOiBRZ3JpZENvbnRlbnRbXSB7XG4gIGlmICghaW1hZ2VzPy5sZW5ndGgpIHJldHVybiBjb250ZW50O1xuICByZXR1cm4gW1xuICAgIC4uLmNvbnRlbnQsXG4gICAgLi4uaW1hZ2VzLm1hcChcbiAgICAgIChpbWcpOiBRZ3JpZENvbnRlbnQgPT4gKHtcbiAgICAgICAgdHlwZTogXCJpbWFnZVwiLFxuICAgICAgICBkYXRhOiBpbWcuZGF0YSxcbiAgICAgICAgcmV2aXNlZFByb21wdDogaW1nLnJldmlzZWRQcm9tcHQgPz8gbnVsbCxcbiAgICAgIH0pLFxuICAgICksXG4gIF07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBidWlsZFRvb2xDYWxsU2NoZW1hKHRvb2xzOiBRZ3JpZFRvb2xbXSk6IEpzb25WYWx1ZSB7XG4gIGNvbnN0IHRvb2xEZXNjcmlwdGlvbnMgPSB0b29sc1xuICAgIC5tYXAoKHRvb2wpID0+IHtcbiAgICAgIGNvbnN0IHNjaGVtYSA9IEpTT04uc3RyaW5naWZ5KHRvb2wuaW5wdXRTY2hlbWEpO1xuICAgICAgcmV0dXJuIGAtICR7dG9vbC5uYW1lfTogJHt0b29sLmRlc2NyaXB0aW9uID8/IFwiXCJ9XFxuICBpbnB1dFNjaGVtYTogJHtzY2hlbWF9YDtcbiAgICB9KVxuICAgIC5qb2luKFwiXFxuXCIpO1xuXG4gIHJldHVybiB7XG4gICAgdHlwZTogXCJvYmplY3RcIixcbiAgICBkZXNjcmlwdGlvbjpcbiAgICAgIFwiVXNlIHRoaXMgc2NoZW1hIG9ubHkgdGhyb3VnaCBTdHJ1Y3R1cmVkT3V0cHV0LiBEbyBub3QgaW52b2tlIGxpc3RlZCBjbGllbnQgdG9vbHMgYXMgbmF0aXZlIENsYXVkZSBDb2RlIHRvb2xzLiBUbyByZXF1ZXN0IGNsaWVudC1zaWRlIHRvb2wgZXhlY3V0aW9uLCBzZXQgYWN0aW9uIHRvIHRvb2xfY2FsbCBhbmQgaW5jbHVkZSB0b29sQ2FsbHMuIFVzZSBhY3Rpb24gYW5zd2VyIG9ubHkgd2hlbiBubyBmdXJ0aGVyIGNsaWVudCB0b29sIHJlc3VsdCBpcyBuZWVkZWQuXCIsXG4gICAgcHJvcGVydGllczoge1xuICAgICAgYWN0aW9uOiB7XG4gICAgICAgIHR5cGU6IFwic3RyaW5nXCIsXG4gICAgICAgIGVudW06IFtcImFuc3dlclwiLCBcInRvb2xfY2FsbFwiXSxcbiAgICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICAgXCJVc2UgdG9vbF9jYWxsIHRvIHJlcXVlc3QgY2xpZW50LXNpZGUgdG9vbCBleGVjdXRpb24gdGhyb3VnaCB0aGlzIHN0cnVjdHVyZWQgb3V0cHV0LiBVc2UgYW5zd2VyIG9ubHkgZm9yIGEgZmluYWwgYW5zd2VyLlwiLFxuICAgICAgfSxcbiAgICAgIGFuc3dlcjogeyBhbnlPZjogW3sgdHlwZTogXCJzdHJpbmdcIiB9LCB7IHR5cGU6IFwibnVsbFwiIH1dIH0sXG4gICAgICB0b29sQ2FsbHM6IHtcbiAgICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICAgXCJDbGllbnQtc2lkZSB0b29sIGNhbGxzIHJlcXVlc3RlZCB0aHJvdWdoIHN0cnVjdHVyZWQgb3V0cHV0LiBEbyBub3QgY2FsbCB0aGVzZSB0b29scyBhcyBuYXRpdmUgQ2xhdWRlIENvZGUgdG9vbHMuXCIsXG4gICAgICAgIGFueU9mOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgdHlwZTogXCJhcnJheVwiLFxuICAgICAgICAgICAgaXRlbXM6IHtcbiAgICAgICAgICAgICAgdHlwZTogXCJvYmplY3RcIixcbiAgICAgICAgICAgICAgcHJvcGVydGllczoge1xuICAgICAgICAgICAgICAgIHRvb2xOYW1lOiB7XG4gICAgICAgICAgICAgICAgICB0eXBlOiBcInN0cmluZ1wiLFxuICAgICAgICAgICAgICAgICAgZW51bTogdG9vbHMubWFwKCh0b29sKSA9PiB0b29sLm5hbWUpLFxuICAgICAgICAgICAgICAgICAgZGVzY3JpcHRpb246IGBDbGllbnQtc2lkZSB0b29sIG5hbWUgdG8gcmVxdWVzdCB0aHJvdWdoIHN0cnVjdHVyZWQgb3V0cHV0LiBEbyBub3QgY2FsbCB0aGlzIGFzIGEgbmF0aXZlIENsYXVkZSBDb2RlIHRvb2wuXFxuJHt0b29sRGVzY3JpcHRpb25zfWAsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBhcmdzOiB7XG4gICAgICAgICAgICAgICAgICB0eXBlOiBcInN0cmluZ1wiLFxuICAgICAgICAgICAgICAgICAgZGVzY3JpcHRpb246IFwiVG9vbCBhcmd1bWVudHMgYXMgYSBKU09OIHN0cmluZyBmb3IgdGhlIGNsaWVudC1zaWRlIHRvb2wuXCIsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgcmVxdWlyZWQ6IFtcInRvb2xOYW1lXCIsIFwiYXJnc1wiXSxcbiAgICAgICAgICAgICAgYWRkaXRpb25hbFByb3BlcnRpZXM6IGZhbHNlLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHsgdHlwZTogXCJudWxsXCIgfSxcbiAgICAgICAgXSxcbiAgICAgIH0sXG4gICAgfSxcbiAgICByZXF1aXJlZDogW1wiYWN0aW9uXCIsIFwiYW5zd2VyXCIsIFwidG9vbENhbGxzXCJdLFxuICAgIGFkZGl0aW9uYWxQcm9wZXJ0aWVzOiBmYWxzZSxcbiAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGFwcGx5VG9vbENhbGxFbXVsYXRpb24oXG4gIHJlc3VsdDogT21pdDxRdWVyeU91dHB1dCwgXCJjb250ZW50XCIgfCBcImZpbmlzaFJlYXNvblwiIHwgXCJydW5Db250ZXh0XCI+LFxuICB0b29scz86IFFncmlkVG9vbFtdLFxuICB0aHJlYWRDb29yZD86IFFncmlkVGhyZWFkQ29vcmQsXG4gIGltYWdlcz86IEVtdWxhdGlvbkltYWdlW10sXG4pOiBRdWVyeU91dHB1dCB7XG4gIC8vIHRocmVhZCDsnqzsgqzsmqkg7KKM7ZGc66W8IHJ1bkNvbnRleHQg66GcIOyLpOyWtCDsmKzrprDri6QgKGF1dG8g66qo65Oc64qUIHJlcXVlc3RMb2dJZCDsl4bsnbQgdGhyZWFkQ29vcmQg66eMKS5cbiAgY29uc3QgcnVuQ29udGV4dCA9IHRocmVhZENvb3JkID8geyB0aHJlYWRDb29yZCB9IDogdW5kZWZpbmVkO1xuICAvLyDsnbTrr7jsp4DripQgZmluaXNoUmVhc29uIOqzvCDsp4HqtZDtlZjripQgY29udGVudCDtjIztirguIOyhsOumveuQnCBjb250ZW50IOuSpOyXkCBhcHBlbmQg7ZWc64ukLlxuXG4gIGlmICghdG9vbHM/Lmxlbmd0aCkge1xuICAgIGNvbnN0IGNvbnRlbnQ6IFFncmlkQ29udGVudFtdID0gW3sgdHlwZTogXCJ0ZXh0XCIsIHRleHQ6IHJlc3VsdC50ZXh0IH1dO1xuICAgIHJldHVybiB7IC4uLnJlc3VsdCwgY29udGVudDogYXBwZW5kSW1hZ2VzKGNvbnRlbnQsIGltYWdlcyksIGZpbmlzaFJlYXNvbjogXCJzdG9wXCIsIHJ1bkNvbnRleHQgfTtcbiAgfVxuXG4gIGxldCBwYXJzZWQ6IFRvb2xDYWxsUmVzcG9uc2U7XG4gIHRyeSB7XG4gICAgcGFyc2VkID0gSlNPTi5wYXJzZShyZXN1bHQudGV4dCkgYXMgVG9vbENhbGxSZXNwb25zZTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIGxvZ2dlci53YXJuKGB0b29sLWNhbGwgZW11bGF0aW9uIHBhcnNlIGZhaWxlZCwgZmFsbGluZyBiYWNrIHRvIHRleHQ6ICR7KGUgYXMgRXJyb3IpLm1lc3NhZ2V9YCk7XG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLnJlc3VsdCxcbiAgICAgIGNvbnRlbnQ6IGFwcGVuZEltYWdlcyhbeyB0eXBlOiBcInRleHRcIiwgdGV4dDogcmVzdWx0LnRleHQgfV0sIGltYWdlcyksXG4gICAgICBmaW5pc2hSZWFzb246IFwic3RvcFwiLFxuICAgICAgcnVuQ29udGV4dCxcbiAgICB9O1xuICB9XG5cbiAgaWYgKHBhcnNlZC5hY3Rpb24gPT09IFwidG9vbF9jYWxsXCIpIHtcbiAgICBjb25zdCB0b29sQ2FsbHMgPSBwYXJzZWQudG9vbENhbGxzID8/IFtdO1xuICAgIGNvbnN0IGNvbnRlbnQ6IFFncmlkQ29udGVudFtdID0gdG9vbENhbGxzLm1hcCgodG9vbENhbGwpID0+IHtcbiAgICAgIGlmICghdG9vbHMuc29tZSgodG9vbCkgPT4gdG9vbC5uYW1lID09PSB0b29sQ2FsbC50b29sTmFtZSkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGB1bmtub3duIGVtdWxhdGVkIHRvb2w6ICR7dG9vbENhbGwudG9vbE5hbWV9YCk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIHR5cGU6IFwidG9vbC1jYWxsXCIsXG4gICAgICAgIHRvb2xDYWxsSWQ6IGBjYWxsXyR7TWF0aC5yYW5kb20oKS50b1N0cmluZygzNikuc2xpY2UoMiwgMTApfWAsXG4gICAgICAgIHRvb2xOYW1lOiB0b29sQ2FsbC50b29sTmFtZSxcbiAgICAgICAgaW5wdXQ6IHRvb2xDYWxsLmFyZ3MsXG4gICAgICB9O1xuICAgIH0pO1xuICAgIHJldHVybiB7XG4gICAgICAuLi5yZXN1bHQsXG4gICAgICBjb250ZW50OiBhcHBlbmRJbWFnZXMoY29udGVudCwgaW1hZ2VzKSxcbiAgICAgIGZpbmlzaFJlYXNvbjogXCJ0b29sLWNhbGxzXCIsXG4gICAgICBydW5Db250ZXh0LFxuICAgIH07XG4gIH1cblxuICBjb25zdCB0ZXh0ID0gcGFyc2VkLmFuc3dlciA/PyByZXN1bHQudGV4dDtcbiAgcmV0dXJuIHtcbiAgICAuLi5yZXN1bHQsXG4gICAgdGV4dCxcbiAgICBjb250ZW50OiBhcHBlbmRJbWFnZXMoW3sgdHlwZTogXCJ0ZXh0XCIsIHRleHQgfV0sIGltYWdlcyksXG4gICAgZmluaXNoUmVhc29uOiBcInN0b3BcIixcbiAgICBydW5Db250ZXh0LFxuICB9O1xufVxuIl0sIm1hcHBpbmdzIjoiOztBQVVBLE1BQU0sU0FBUyxVQUFVLENBQUMsU0FBUyxnQkFB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
139
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG9vbC1lbXVsYXRpb24uanMiLCJuYW1lcyI6W10sInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2FwcGxpY2F0aW9uL3FncmlkL3Rvb2wtZW11bGF0aW9uLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEJ1ZmZlciB9IGZyb20gXCJub2RlOmJ1ZmZlclwiO1xuXG5pbXBvcnQgeyBnZXRMb2dnZXIgfSBmcm9tIFwiQGxvZ3RhcGUvbG9ndGFwZVwiO1xuaW1wb3J0IHsgeiB9IGZyb20gXCJ6b2RcIjtcblxuLy8g7J2R64u1KOuqqOuNuCDstpzroKUpIGVudmVsb3BlIOydmCDsnpDsm5Ag7ZWc64+ELiBjYWxsZXIg7Iqk7YKk66eIIOyghOyymOumrCDtlZzrj4QoQ0FMTEVSX1NDSEVNQV9MSU1JVFMp7JmAIOqwkuydtFxuLy8g6rCZ7JWEIOuztOyXrOuPhCDshJzroZwg64uk66W4IOyekOybkOydhCDsp4DtgqTripQg64+F66a9IOyDgeyImOuLpCDigJQg7Iqk7YKk66eIIOq5iuydtOuKlCDsnbjsiqTthLTsiqQg6rmK7J2066W8IGJvdW5kIO2VmOyngFxuLy8g7JWK7Jy866+A66GcKOyerOq3gCAkcmVmIO2XiOyaqSkg7LqY65+sIO2VnOuPhOulvCDsobDsoJXtlbTrj4Qg7J2R64u1IOyImOyaqSDquLDspIDsnbQg65Sw6528IOybgOyngeyXrOyEoCDslYgg65Cc64ukLlxuY29uc3QgU1RSVUNUVVJFRF9FTlZFTE9QRV9MSU1JVFMgPSB7XG4gIG1heFV0ZjhCeXRlczogNTEyICogMTAyNCxcbiAgbWF4Tm9kZXM6IDIwXzAwMCxcbiAgbWF4RGVwdGg6IDEzMixcbn0gYXMgY29uc3Q7XG5pbXBvcnQge1xuICB0eXBlIFFncmlkQ29udGVudCxcbiAgdHlwZSBRZ3JpZFRocmVhZENvb3JkLFxuICB0eXBlIFFncmlkVG9vbCxcbiAgdHlwZSBRdWVyeU91dHB1dCxcbn0gZnJvbSBcIi4vcWdyaWQudHlwZXNcIjtcblxuY29uc3QgbG9nZ2VyID0gZ2V0TG9nZ2VyKFtcInFncmlkXCIsIFwidG9vbC1lbXVsYXRpb25cIl0pO1xuXG50eXBlIEVtdWxhdGlvblJlc3VsdCA9IE9taXQ8UXVlcnlPdXRwdXQsIFwiY29udGVudFwiIHwgXCJmaW5pc2hSZWFzb25cIiB8IFwicnVuQ29udGV4dFwiPjtcbnR5cGUgVG9vbENhbGwgPSB7IHRvb2xOYW1lOiBzdHJpbmc7IGFyZ3M6IHN0cmluZyB9O1xudHlwZSBMZWdhY3lUb29sQ2FsbFJlc3BvbnNlID0ge1xuICBhY3Rpb24/OiBcImFuc3dlclwiIHwgXCJ0b29sX2NhbGxcIjtcbiAgYW5zd2VyPzogc3RyaW5nIHwgbnVsbDtcbiAgdG9vbENhbGxzPzogVG9vbENhbGxbXSB8IG51bGw7XG59O1xuXG5jb25zdCBTdHJ1Y3R1cmVkVG9vbENhbGxSZXNwb25zZSA9IHouZGlzY3JpbWluYXRlZFVuaW9uKFwiYWN0aW9uXCIsIFtcbiAgei5zdHJpY3RPYmplY3Qoe1xuICAgIGFjdGlvbjogei5saXRlcmFsKFwiYW5zd2VyXCIpLFxuICAgIGFuc3dlcjogei5qc29uKCkucmVmaW5lKChhbnN3ZXIpID0+IGFuc3dlciAhPT0gbnVsbCwge1xuICAgICAgbWVzc2FnZTogXCJhbnN3ZXIgbXVzdCBiZSBub24tbnVsbFwiLFxuICAgIH0pLFxuICAgIHRvb2xDYWxsczogei51bmlvbihbei5udWxsKCksIHoudHVwbGUoW10pXSksXG4gIH0pLFxuICB6LnN0cmljdE9iamVjdCh7XG4gICAgYWN0aW9uOiB6LmxpdGVyYWwoXCJ0b29sX2NhbGxcIiksXG4gICAgYW5zd2VyOiB6Lm51bGwoKSxcbiAgICB0b29sQ2FsbHM6IHpcbiAgICAgIC5hcnJheShcbiAgICAgICAgei5zdHJpY3RPYmplY3Qoe1xuICAgICAgICAgIHRvb2xOYW1lOiB6LnN0cmluZygpLFxuICAgICAgICAgIGFyZ3M6IHouc3RyaW5nKCksXG4gICAgICAgIH0pLFxuICAgICAgKVxuICAgICAgLm1pbigxKSxcbiAgfSksXG5dKTtcbnR5cGUgU3RydWN0dXJlZFJlc3BvbnNlID0gei5pbmZlcjx0eXBlb2YgU3RydWN0dXJlZFRvb2xDYWxsUmVzcG9uc2U+O1xuXG5leHBvcnQgY2xhc3MgVG9vbENhbGxFbXVsYXRpb25FcnJvciBleHRlbmRzIEVycm9yIHtcbiAgY29uc3RydWN0b3IobWVzc2FnZTogc3RyaW5nKSB7XG4gICAgc3VwZXIoYHRvb2wtY2FsbCBlbXVsYXRpb246ICR7bWVzc2FnZX1gKTtcbiAgICB0aGlzLm5hbWUgPSBcIlRvb2xDYWxsRW11bGF0aW9uRXJyb3JcIjtcbiAgfVxufVxuXG4vLyBkaXNwYXRjaGVyIOqwgCDrhJjquLDripQg7J2066+47KeAIOqysOqzvC4gcWdyaWQg64qUIGJhc2U2NCBwYXlsb2FkIOunjCDsoITri6ztlZjqs6Ag7Y+s66e37J2AIOuztOyepe2VmOyngCDslYrripTri6QuXG5pbnRlcmZhY2UgRW11bGF0aW9uSW1hZ2Uge1xuICBkYXRhOiBzdHJpbmc7XG4gIHJldmlzZWRQcm9tcHQ/OiBzdHJpbmcgfCBudWxsO1xufVxuXG5pbnRlcmZhY2UgVG9vbENhbGxFbXVsYXRpb25PcHRpb25zIHtcbiAgdGhyZWFkQ29vcmQ/OiBRZ3JpZFRocmVhZENvb3JkO1xuICBpbWFnZXM/OiBFbXVsYXRpb25JbWFnZVtdO1xuICBhbnN3ZXJNb2RlPzogXCJsZWdhY3lcIiB8IFwic3RydWN0dXJlZFwiO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gYXBwbHlUb29sQ2FsbEVtdWxhdGlvbihcbiAgcmVzdWx0OiBFbXVsYXRpb25SZXN1bHQsXG4gIHRvb2xzPzogUWdyaWRUb29sW10sXG4gIG9wdGlvbnM6IFRvb2xDYWxsRW11bGF0aW9uT3B0aW9ucyA9IHt9LFxuKTogUXVlcnlPdXRwdXQge1xuICBjb25zdCB7IHRocmVhZENvb3JkLCBpbWFnZXMsIGFuc3dlck1vZGUgPSBcImxlZ2FjeVwiIH0gPSBvcHRpb25zO1xuICBjb25zdCBydW5Db250ZXh0ID0gdGhyZWFkQ29vcmQgPyB7IHRocmVhZENvb3JkIH0gOiB1bmRlZmluZWQ7XG5cbiAgaWYgKCF0b29scz8ubGVuZ3RoKSB7XG4gICAgcmV0dXJuIGFuc3dlck91dHB1dChyZXN1bHQsIHJlc3VsdC50ZXh0LCBpbWFnZXMsIHJ1bkNvbnRleHQpO1xuICB9XG5cbiAgaWYgKGFuc3dlck1vZGUgPT09IFwibGVnYWN5XCIpIHtcbiAgICByZXR1cm4gYXBwbHlMZWdhY3lSZXNwb25zZShyZXN1bHQsIHRvb2xzLCBpbWFnZXMsIHJ1bkNvbnRleHQpO1xuICB9XG5cbiAgY29uc3QgcGFyc2VkID0gcGFyc2VTdHJ1Y3R1cmVkUmVzcG9uc2UocmVzdWx0LnRleHQsIHRvb2xzKTtcbiAgaWYgKHBhcnNlZC5hY3Rpb24gPT09IFwidG9vbF9jYWxsXCIpIHtcbiAgICByZXR1cm4gdG9vbENhbGxPdXRwdXQocmVzdWx0LCBwYXJzZWQudG9vbENhbGxzLCBpbWFnZXMsIHJ1bkNvbnRleHQpO1xuICB9XG5cbiAgcmV0dXJuIGFuc3dlck91dHB1dChyZXN1bHQsIEpTT04uc3RyaW5naWZ5KHBhcnNlZC5hbnN3ZXIpLCBpbWFnZXMsIHJ1bkNvbnRleHQpO1xufVxuXG4vKipcbiAqIFRvb2xzLW9ubHkgcmVxdWVzdHMga2VlcCB0aGUgcGVybWlzc2l2ZSAyLjUuMyBjb250cmFjdC4gU3RydWN0dXJlZC1vdXRwdXQgcmVxdWVzdHMgdXNlIHRoZVxuICogc3RyaWN0IGRlY29kZXIgYmVsb3cgYmVjYXVzZSB0aGVpciBvdXRlciBhY3Rpb24gZW52ZWxvcGUgaXMgYW4gaW50ZXJuYWwgc2VydmVyIGNvbnRyYWN0LlxuICovXG5mdW5jdGlvbiBhcHBseUxlZ2FjeVJlc3BvbnNlKFxuICByZXN1bHQ6IEVtdWxhdGlvblJlc3VsdCxcbiAgdG9vbHM6IFFncmlkVG9vbFtdLFxuICBpbWFnZXM6IEVtdWxhdGlvbkltYWdlW10gfCB1bmRlZmluZWQsXG4gIHJ1bkNvbnRleHQ6IFF1ZXJ5T3V0cHV0W1wicnVuQ29udGV4dFwiXSxcbik6IFF1ZXJ5T3V0cHV0IHtcbiAgbGV0IHBhcnNlZDogTGVnYWN5VG9vbENhbGxSZXNwb25zZTtcbiAgdHJ5IHtcbiAgICBwYXJzZWQgPSBKU09OLnBhcnNlKHJlc3VsdC50ZXh0KSBhcyBMZWdhY3lUb29sQ2FsbFJlc3BvbnNlO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIGxvZ2dlci53YXJuKFxuICAgICAgYHRvb2wtY2FsbCBlbXVsYXRpb24gcGFyc2UgZmFpbGVkLCBmYWxsaW5nIGJhY2sgdG8gdGV4dDogJHsoZXJyb3IgYXMgRXJyb3IpLm1lc3NhZ2V9YCxcbiAgICApO1xuICAgIHJldHVybiBhbnN3ZXJPdXRwdXQocmVzdWx0LCByZXN1bHQudGV4dCwgaW1hZ2VzLCBydW5Db250ZXh0KTtcbiAgfVxuXG4gIGlmIChwYXJzZWQuYWN0aW9uID09PSBcInRvb2xfY2FsbFwiKSB7XG4gICAgY29uc3QgdG9vbENhbGxzID0gcGFyc2VkLnRvb2xDYWxscyA/PyBbXTtcbiAgICBjb25zdCB1bmtub3duVG9vbCA9IGZpbmRVbmtub3duVG9vbCh0b29sQ2FsbHMsIHRvb2xzKTtcbiAgICBpZiAodW5rbm93blRvb2wgIT09IHVuZGVmaW5lZCkgdGhyb3cgbmV3IEVycm9yKGB1bmtub3duIGVtdWxhdGVkIHRvb2w6ICR7dW5rbm93blRvb2x9YCk7XG4gICAgcmV0dXJuIHRvb2xDYWxsT3V0cHV0KHJlc3VsdCwgdG9vbENhbGxzLCBpbWFnZXMsIHJ1bkNvbnRleHQpO1xuICB9XG5cbiAgcmV0dXJuIGFuc3dlck91dHB1dChyZXN1bHQsIHBhcnNlZC5hbnN3ZXIgPz8gcmVzdWx0LnRleHQsIGltYWdlcywgcnVuQ29udGV4dCk7XG59XG5cbmZ1bmN0aW9uIHBhcnNlU3RydWN0dXJlZFJlc3BvbnNlKHRleHQ6IHN0cmluZywgdG9vbHM6IFFncmlkVG9vbFtdKSB7XG4gIGlmIChCdWZmZXIuYnl0ZUxlbmd0aCh0ZXh0LCBcInV0ZjhcIikgPiBTVFJVQ1RVUkVEX0VOVkVMT1BFX0xJTUlUUy5tYXhVdGY4Qnl0ZXMpIHtcbiAgICB0aHJvdyBuZXcgVG9vbENhbGxFbXVsYXRpb25FcnJvcihcbiAgICAgIGBzdHJ1Y3R1cmVkLW91dHB1dCBlbnZlbG9wZSBleGNlZWRzIFVURi04IGJ5dGUgbGltaXQgb2YgJHtTVFJVQ1RVUkVEX0VOVkVMT1BFX0xJTUlUUy5tYXhVdGY4Qnl0ZXN9YCxcbiAgICApO1xuICB9XG5cbiAgbGV0IHZhbHVlOiB1bmtub3duO1xuICB0cnkge1xuICAgIHZhbHVlID0gSlNPTi5wYXJzZSh0ZXh0KTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICB0aHJvdyBuZXcgVG9vbENhbGxFbXVsYXRpb25FcnJvcihcbiAgICAgIGBpbnZhbGlkIHN0cnVjdHVyZWQtb3V0cHV0IGVudmVsb3BlOiAkeyhlcnJvciBhcyBFcnJvcikubWVzc2FnZX1gLFxuICAgICk7XG4gIH1cblxuICBhc3NlcnRTdHJ1Y3R1cmVkRW52ZWxvcGVDb21wbGV4aXR5KHZhbHVlKTtcbiAgY29uc3QgdmFsaWRhdGlvbiA9IFN0cnVjdHVyZWRUb29sQ2FsbFJlc3BvbnNlLnNhZmVQYXJzZSh2YWx1ZSk7XG4gIGlmICghdmFsaWRhdGlvbi5zdWNjZXNzKSB7XG4gICAgY29uc3QgaXNzdWUgPSB2YWxpZGF0aW9uLmVycm9yLmlzc3Vlc1swXTtcbiAgICBjb25zdCBwYXRoID0gaXNzdWUgJiYgaXNzdWUucGF0aC5sZW5ndGggPiAwID8gYCBhdCAke2lzc3VlLnBhdGguam9pbihcIi5cIil9YCA6IFwiXCI7XG4gICAgY29uc3QgZGV0YWlsID0gaXNzdWU/Lm1lc3NhZ2UgPz8gXCJ1bmtub3duIHZhbGlkYXRpb24gaXNzdWVcIjtcbiAgICB0aHJvdyBuZXcgVG9vbENhbGxFbXVsYXRpb25FcnJvcihgaW52YWxpZCBzdHJ1Y3R1cmVkLW91dHB1dCBlbnZlbG9wZSR7cGF0aH06ICR7ZGV0YWlsfWApO1xuICB9XG5cbiAgLy8gWm9kIGNsb25lcyBKU09OIG9iamVjdHMgYW5kIGRyb3BzIG93biBcIl9fcHJvdG9fX1wiIGtleXMuIFRoZSBwYXJzZWQgSlNPTiBpcyBzYWZlIHRvIHJldHVyblxuICAvLyBhZnRlciB2YWxpZGF0aW9uIGFuZCBwcmVzZXJ2ZXMgdGhlIGNhbGxlcidzIGV4YWN0IHN0cnVjdHVyZWQgdmFsdWUuXG4gIGNvbnN0IHJlc3BvbnNlID0gdmFsdWUgYXMgU3RydWN0dXJlZFJlc3BvbnNlO1xuICBpZiAocmVzcG9uc2UuYWN0aW9uID09PSBcInRvb2xfY2FsbFwiKSB7XG4gICAgY29uc3QgdW5rbm93blRvb2wgPSBmaW5kVW5rbm93blRvb2wocmVzcG9uc2UudG9vbENhbGxzLCB0b29scyk7XG4gICAgaWYgKHVua25vd25Ub29sICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHRocm93IG5ldyBUb29sQ2FsbEVtdWxhdGlvbkVycm9yKGB1bmtub3duIGVtdWxhdGVkIHRvb2w6ICR7dW5rbm93blRvb2x9YCk7XG4gICAgfVxuICB9XG4gIHJldHVybiByZXNwb25zZTtcbn1cblxuZnVuY3Rpb24gdG9vbENhbGxPdXRwdXQoXG4gIHJlc3VsdDogRW11bGF0aW9uUmVzdWx0LFxuICB0b29sQ2FsbHM6IFRvb2xDYWxsW10sXG4gIGltYWdlczogRW11bGF0aW9uSW1hZ2VbXSB8IHVuZGVmaW5lZCxcbiAgcnVuQ29udGV4dDogUXVlcnlPdXRwdXRbXCJydW5Db250ZXh0XCJdLFxuKTogUXVlcnlPdXRwdXQge1xuICByZXR1cm4ge1xuICAgIC4uLnJlc3VsdCxcbiAgICBjb250ZW50OiBhcHBlbmRJbWFnZXMoXG4gICAgICB0b29sQ2FsbHMubWFwKCh0b29sQ2FsbCkgPT4gKHtcbiAgICAgICAgdHlwZTogXCJ0b29sLWNhbGxcIixcbiAgICAgICAgdG9vbENhbGxJZDogYGNhbGxfJHtNYXRoLnJhbmRvbSgpLnRvU3RyaW5nKDM2KS5zbGljZSgyLCAxMCl9YCxcbiAgICAgICAgdG9vbE5hbWU6IHRvb2xDYWxsLnRvb2xOYW1lLFxuICAgICAgICBpbnB1dDogdG9vbENhbGwuYXJncyxcbiAgICAgIH0pKSxcbiAgICAgIGltYWdlcyxcbiAgICApLFxuICAgIGZpbmlzaFJlYXNvbjogXCJ0b29sLWNhbGxzXCIsXG4gICAgcnVuQ29udGV4dCxcbiAgfTtcbn1cblxuZnVuY3Rpb24gYW5zd2VyT3V0cHV0KFxuICByZXN1bHQ6IEVtdWxhdGlvblJlc3VsdCxcbiAgdGV4dDogc3RyaW5nLFxuICBpbWFnZXM6IEVtdWxhdGlvbkltYWdlW10gfCB1bmRlZmluZWQsXG4gIHJ1bkNvbnRleHQ6IFF1ZXJ5T3V0cHV0W1wicnVuQ29udGV4dFwiXSxcbik6IFF1ZXJ5T3V0cHV0IHtcbiAgcmV0dXJuIHtcbiAgICAuLi5yZXN1bHQsXG4gICAgdGV4dCxcbiAgICBjb250ZW50OiBhcHBlbmRJbWFnZXMoW3sgdHlwZTogXCJ0ZXh0XCIsIHRleHQgfV0sIGltYWdlcyksXG4gICAgZmluaXNoUmVhc29uOiBcInN0b3BcIixcbiAgICBydW5Db250ZXh0LFxuICB9O1xufVxuXG5mdW5jdGlvbiBmaW5kVW5rbm93blRvb2wodG9vbENhbGxzOiBUb29sQ2FsbFtdLCB0b29sczogUWdyaWRUb29sW10pOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICBjb25zdCBrbm93blRvb2xOYW1lcyA9IG5ldyBTZXQodG9vbHMubWFwKCh0b29sKSA9PiB0b29sLm5hbWUpKTtcbiAgcmV0dXJuIHRvb2xDYWxscy5maW5kKCh0b29sQ2FsbCkgPT4gIWtub3duVG9vbE5hbWVzLmhhcyh0b29sQ2FsbC50b29sTmFtZSkpPy50b29sTmFtZTtcbn1cblxuZnVuY3Rpb24gYXBwZW5kSW1hZ2VzKGNvbnRlbnQ6IFFncmlkQ29udGVudFtdLCBpbWFnZXM/OiBFbXVsYXRpb25JbWFnZVtdKTogUWdyaWRDb250ZW50W10ge1xuICBpZiAoIWltYWdlcz8ubGVuZ3RoKSByZXR1cm4gY29udGVudDtcbiAgcmV0dXJuIFtcbiAgICAuLi5jb250ZW50LFxuICAgIC4uLmltYWdlcy5tYXAoXG4gICAgICAoaW1hZ2UpOiBRZ3JpZENvbnRlbnQgPT4gKHtcbiAgICAgICAgdHlwZTogXCJpbWFnZVwiLFxuICAgICAgICBkYXRhOiBpbWFnZS5kYXRhLFxuICAgICAgICByZXZpc2VkUHJvbXB0OiBpbWFnZS5yZXZpc2VkUHJvbXB0ID8/IG51bGwsXG4gICAgICB9KSxcbiAgICApLFxuICBdO1xufVxuXG5mdW5jdGlvbiBhc3NlcnRTdHJ1Y3R1cmVkRW52ZWxvcGVDb21wbGV4aXR5KHJvb3Q6IHVua25vd24pOiB2b2lkIHtcbiAgY29uc3QgbWF4RGVwdGggPSBTVFJVQ1RVUkVEX0VOVkVMT1BFX0xJTUlUUy5tYXhEZXB0aDtcbiAgY29uc3Qgc3RhY2sgPSBbeyB2YWx1ZTogcm9vdCwgZGVwdGg6IDAgfV07XG4gIGxldCBub2RlcyA9IDA7XG5cbiAgd2hpbGUgKHN0YWNrLmxlbmd0aCA+IDApIHtcbiAgICBjb25zdCBjdXJyZW50ID0gc3RhY2sucG9wKCkhO1xuICAgIG5vZGVzICs9IDE7XG4gICAgaWYgKG5vZGVzID4gU1RSVUNUVVJFRF9FTlZFTE9QRV9MSU1JVFMubWF4Tm9kZXMpIHtcbiAgICAgIHRocm93IG5ldyBUb29sQ2FsbEVtdWxhdGlvbkVycm9yKFxuICAgICAgICBgc3RydWN0dXJlZC1vdXRwdXQgZW52ZWxvcGUgZXhjZWVkcyBub2RlIGxpbWl0IG9mICR7U1RSVUNUVVJFRF9FTlZFTE9QRV9MSU1JVFMubWF4Tm9kZXN9YCxcbiAgICAgICk7XG4gICAgfVxuICAgIGlmIChjdXJyZW50LmRlcHRoID4gbWF4RGVwdGgpIHtcbiAgICAgIHRocm93IG5ldyBUb29sQ2FsbEVtdWxhdGlvbkVycm9yKFxuICAgICAgICBgc3RydWN0dXJlZC1vdXRwdXQgZW52ZWxvcGUgZXhjZWVkcyBkZXB0aCBsaW1pdCBvZiAke21heERlcHRofWAsXG4gICAgICApO1xuICAgIH1cbiAgICBpZiAodHlwZW9mIGN1cnJlbnQudmFsdWUgPT09IFwibnVtYmVyXCIgJiYgIU51bWJlci5pc0Zpbml0ZShjdXJyZW50LnZhbHVlKSkge1xuICAgICAgdGhyb3cgbmV3IFRvb2xDYWxsRW11bGF0aW9uRXJyb3IoXCJhbnN3ZXIgbXVzdCBiZSB2YWxpZCBKU09OXCIpO1xuICAgIH1cbiAgICBpZiAoY3VycmVudC52YWx1ZSA9PT0gbnVsbCB8fCB0eXBlb2YgY3VycmVudC52YWx1ZSAhPT0gXCJvYmplY3RcIikgY29udGludWU7XG5cbiAgICBmb3IgKGNvbnN0IHZhbHVlIG9mIE9iamVjdC52YWx1ZXMoY3VycmVudC52YWx1ZSkpIHtcbiAgICAgIHN0YWNrLnB1c2goeyB2YWx1ZSwgZGVwdGg6IGN1cnJlbnQuZGVwdGggKyAxIH0pO1xuICAgIH1cbiAgfVxufVxuIl0sIm1hcHBpbmdzIjoiOzs7O0FBUUEsTUFBTSw2QkFBNkI7Q0FDakMsY0FBYyxNQUFNO0NBQ3BCLFVBQVU7Q0FDVixVQUFVO0FBQ1o7QUFRQSxNQUFNLFNBQVMsVUFBVSxDQUFDLFNBQVMsZ0JBQWdCLENBQUM7QUFVcEQsTUFBTSw2QkFBNkIsRUFBRSxtQkFBbUIsVUFBVSxDQUNoRSxFQUFFLGFBQWE7Q0FDYixRQUFRLEVBQUUsUUFBUSxRQUFRO0NBQzFCLFFBQVEsRUFBRSxLQUFLLENBQUMsQ0FBQyxRQUFRLFdBQVcsV0FBVyxNQUFNLEVBQ25ELFNBQVMsMEJBQ1gsQ0FBQztDQUNELFdBQVcsRUFBRSxNQUFNLENBQUMsRUFBRSxLQUFLLEdBQUcsRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDNUMsQ0FBQyxHQUNELEVBQUUsYUFBYTtDQUNiLFFBQVEsRUFBRSxRQUFRLFdBQVc7Q0FDN0IsUUFBUSxFQUFFLEtBQUs7Q0FDZixXQUFXLEVBQ1IsTUFDQyxFQUFFLGFBQWE7RUFDYixVQUFVLEVBQUUsT0FBTztFQUNuQixNQUFNLEVBQUUsT0FBTztDQUNqQixDQUFDLENBQ0gsQ0FBQyxDQUNBLElBQUksQ0FBQztBQUNWLENBQUMsQ0FDSCxDQUFDO0FBR0QsSUFBYSx5QkFBYixjQUE0QyxNQUFNO0NBQ2hELFlBQVksU0FBaUI7RUFDM0IsTUFBTSx3QkFBd0IsU0FBUztFQUN2QyxLQUFLLE9BQU87Q0FDZDtBQUNGO0FBY0EsU0FBZ0IsdUJBQ2QsUUFDQSxPQUNBLFVBQW9DLENBQUMsR0FDeEI7Q0FDYixNQUFNLEVBQUUsYUFBYSxRQUFRLGFBQWEsYUFBYTtDQUN2RCxNQUFNLGFBQWEsY0FB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
@@ -1,8 +1,8 @@
1
- import { SD } from "../../i18n/sd.generated.js";
2
- import { requestLogLoaderQueries, requestLogSubsetQueries } from "../sonamu.generated.sso.js";
1
+ import { calculateCostUsd } from "../../utils/providers/common/model-cost.js";
3
2
  import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.140.0/helpers/esm/decorateMetadata.js";
4
3
  import __decorate from "../../_virtual/_@oxc-project_runtime@0.140.0/helpers/esm/decorate.js";
5
- import { calculateCostUsd } from "../../utils/providers/common/model-cost.js";
4
+ import { SD } from "../../i18n/sd.generated.js";
5
+ import { requestLogLoaderQueries, requestLogSubsetQueries } from "../sonamu.generated.sso.js";
6
6
  import { BadRequestException, BaseModelClass, NotFoundException, Puri, api, asArray, exhaustive, transactional } from "sonamu";
7
7
  //#region src/application/request-log/request-log.model.ts
8
8
  const MICRO_USD = 1e6;
@@ -1,7 +1,7 @@
1
- import { SD } from "../../i18n/sd.generated.js";
2
- import { requestLogStepLoaderQueries, requestLogStepSubsetQueries } from "../sonamu.generated.sso.js";
3
1
  import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.140.0/helpers/esm/decorateMetadata.js";
4
2
  import __decorate from "../../_virtual/_@oxc-project_runtime@0.140.0/helpers/esm/decorate.js";
3
+ import { SD } from "../../i18n/sd.generated.js";
4
+ import { requestLogStepLoaderQueries, requestLogStepSubsetQueries } from "../sonamu.generated.sso.js";
5
5
  import { BadRequestException, BaseModelClass, NotFoundException, api, asArray, exhaustive } from "sonamu";
6
6
  //#region src/application/request-log-step/request-log-step.model.ts
7
7
  var RequestLogStepModelClass = class extends BaseModelClass {
@@ -1,7 +1,7 @@
1
- import { SD } from "../../i18n/sd.generated.js";
2
- import { tokenLoaderQueries, tokenSubsetQueries } from "../sonamu.generated.sso.js";
3
1
  import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.140.0/helpers/esm/decorateMetadata.js";
4
2
  import __decorate from "../../_virtual/_@oxc-project_runtime@0.140.0/helpers/esm/decorate.js";
3
+ import { SD } from "../../i18n/sd.generated.js";
4
+ import { tokenLoaderQueries, tokenSubsetQueries } from "../sonamu.generated.sso.js";
5
5
  import { BadRequestException, BaseModelClass, NotFoundException, api, asArray, exhaustive } from "sonamu";
6
6
  //#region src/application/token/token.model.ts
7
7
  const DEFAULT_QUOTA_THRESHOLD = 80;
@@ -0,0 +1,15 @@
1
+ import { isSoException } from "sonamu";
2
+ import { getLogger } from "@logtape/logtape";
3
+ //#region src/server-error-handler.ts
4
+ function handleServerError(error, reply) {
5
+ getLogger(["qgrid"]).error(`${error}`);
6
+ const statusCode = isSoException(error) && Number.isInteger(error.statusCode) && error.statusCode >= 400 && error.statusCode <= 599 ? error.statusCode : 500;
7
+ reply.status(statusCode).send({
8
+ name: error.name,
9
+ message: error.message
10
+ });
11
+ }
12
+ //#endregion
13
+ export { handleServerError };
14
+
15
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VydmVyLWVycm9yLWhhbmRsZXIuanMiLCJuYW1lcyI6W10sInNvdXJjZXMiOlsiLi4vc3JjL3NlcnZlci1lcnJvci1oYW5kbGVyLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGdldExvZ2dlciB9IGZyb20gXCJAbG9ndGFwZS9sb2d0YXBlXCI7XG5pbXBvcnQgeyB0eXBlIEZhc3RpZnlSZXBseSB9IGZyb20gXCJmYXN0aWZ5XCI7XG5pbXBvcnQgeyBpc1NvRXhjZXB0aW9uIH0gZnJvbSBcInNvbmFtdVwiO1xuXG4vLyBzdGF0dXNDb2RlIOulvCDsi6DrorDtlZjripQg67KU7JyE66W8IFNvbmFtdSDsmIjsmbgg6rOE7JW9KGlzU29FeGNlcHRpb24p7Jy866GcIO2VnOygle2VnOuLpC4gcWdyaWQg64qUIO2UhOuhneyLnOudvFxuLy8gdXBzdHJlYW0gSFRUUCDsmKTrpZgoZmV0Y2gvdW5kaWNpIOulmCnrj4Qgc3RhdHVzQ29kZSDrpbwg64us6rOgIOuCmOyYpOuKlOuNsCwg6re46rG4IGR1Y2stdHlwaW5nIOycvOuhnFxuLy8g6re464yA66GcIOyXkOy9lO2VmOuptCB1cHN0cmVhbSDsnZggNDAxLzQyOSDqsIAg7Zi47Lac7J6QIOyekOyLoOydmCDsmKTrpZjroZwg65GU6rCR7ZWc64ukLiBTb25hbXUg7JiI7Jm46rCAIOyVhOuLiOuptCA1MDAuXG5leHBvcnQgZnVuY3Rpb24gaGFuZGxlU2VydmVyRXJyb3IoZXJyb3I6IEVycm9yLCByZXBseTogRmFzdGlmeVJlcGx5KTogdm9pZCB7XG4gIGdldExvZ2dlcihbXCJxZ3JpZFwiXSkuZXJyb3IoYCR7ZXJyb3J9YCk7XG4gIGNvbnN0IHN0YXR1c0NvZGUgPVxuICAgIGlzU29FeGNlcHRpb24oZXJyb3IpICYmXG4gICAgTnVtYmVyLmlzSW50ZWdlcihlcnJvci5zdGF0dXNDb2RlKSAmJlxuICAgIGVycm9yLnN0YXR1c0NvZGUgPj0gNDAwICYmXG4gICAgZXJyb3Iuc3RhdHVzQ29kZSA8PSA1OTlcbiAgICAgID8gZXJyb3Iuc3RhdHVzQ29kZVxuICAgICAgOiA1MDA7XG5cbiAgcmVwbHkuc3RhdHVzKHN0YXR1c0NvZGUpLnNlbmQoe1xuICAgIG5hbWU6IGVycm9yLm5hbWUsXG4gICAgbWVzc2FnZTogZXJyb3IubWVzc2FnZSxcbiAgfSk7XG59XG4iXSwibWFwcGluZ3MiOiI7OztBQU9BLFNBQWdCLGtCQUFrQixPQUFjLE9BQTJCO0NBQ3pFLFVBQVUsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLE1BQU0sR0FBRyxPQUFPO0NBQ3JDLE1BQU0sYUFDSixjQUFjLEtBQUssS0FDbkIsT0FBTyxVQUFVLE1BQU0sVUFBVSxLQUNqQyxNQUFNLGNBQWMsT0FDcEIsTUFBTSxjQUFjLE1BQ2hCLE1BQU0sYUFDTjtDQUVOLE1BQU0sT0FBTyxVQUFVLENBQUMsQ0FBQyxLQUFLO0VBQzVCLE1BQU0sTUFBTTtFQUNaLFNBQVMsTUFBTTtDQUNqQixDQUFDO0FBQ0gifQ==
@@ -1,10 +1,11 @@
1
1
  import { monitLogSink } from "./application/monit/log-buffer.js";
2
- import { OpenAIDispatcher } from "./utils/providers/openai/openai-dispatcher.js";
3
2
  import { QgridDispatcher } from "./application/qgrid/qgrid.dispatcher.js";
4
3
  import { QgridFrame } from "./application/qgrid/qgrid.frame.js";
5
4
  import { TokenSubscriber } from "./application/qgrid/token-subscriber.js";
6
5
  import { ensureTokensTrigger } from "./application/qgrid/token-trigger-setup.js";
6
+ import { handleServerError } from "./server-error-handler.js";
7
7
  import { AnthropicDispatcher } from "./utils/providers/anthropic/anthropic-dispatcher.js";
8
+ import { OpenAIDispatcher } from "./utils/providers/openai/openai-dispatcher.js";
8
9
  import { CachePresets, defineConfig } from "sonamu";
9
10
  import { getConsoleSink, getLogger } from "@logtape/logtape";
10
11
  import { drivers, store } from "sonamu/cache";
@@ -171,11 +172,7 @@ var sonamu_config_default = defineConfig({
171
172
  log.info("graceful shutdown");
172
173
  },
173
174
  onError: (error, _request, reply) => {
174
- getLogger(["qgrid"]).error(`${error}`);
175
- reply.status(500).send({
176
- name: error.name,
177
- message: error.message
178
- });
175
+ handleServerError(error, reply);
179
176
  }
180
177
  }
181
178
  }
@@ -183,4 +180,4 @@ var sonamu_config_default = defineConfig({
183
180
  //#endregion
184
181
  export { sonamu_config_default as default };
185
182
 
186
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic29uYW11LmNvbmZpZy5qcyIsIm5hbWVzIjpbImNhY2hlRHJpdmVycyJdLCJzb3VyY2VzIjpbIi4uL3NyYy9zb25hbXUuY29uZmlnLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBwYXRoIGZyb20gXCJwYXRoXCI7XG5cbmltcG9ydCB7IGdldENvbnNvbGVTaW5rIH0gZnJvbSBcIkBsb2d0YXBlL2xvZ3RhcGVcIjtcbmltcG9ydCB7IGdldExvZ2dlciB9IGZyb20gXCJAbG9ndGFwZS9sb2d0YXBlXCI7XG5pbXBvcnQgeyBnZXRQcmV0dHlGb3JtYXR0ZXIgfSBmcm9tIFwiQGxvZ3RhcGUvcHJldHR5XCI7XG5pbXBvcnQgeyBDYWNoZVByZXNldHMsIGRlZmluZUNvbmZpZyB9IGZyb20gXCJzb25hbXVcIjtcbmltcG9ydCB7IGRyaXZlcnMgYXMgY2FjaGVEcml2ZXJzLCBzdG9yZSB9IGZyb20gXCJzb25hbXUvY2FjaGVcIjtcblxuaW1wb3J0IHsgbW9uaXRMb2dTaW5rIH0gZnJvbSBcIi4vYXBwbGljYXRpb24vbW9uaXQvbG9nLWJ1ZmZlclwiO1xuaW1wb3J0IHsgUWdyaWREaXNwYXRjaGVyIH0gZnJvbSBcIi4vYXBwbGljYXRpb24vcWdyaWQvcWdyaWQuZGlzcGF0Y2hlclwiO1xuaW1wb3J0IHsgUWdyaWRGcmFtZSB9IGZyb20gXCIuL2FwcGxpY2F0aW9uL3FncmlkL3FncmlkLmZyYW1lXCI7XG5pbXBvcnQgeyBUb2tlblN1YnNjcmliZXIgfSBmcm9tIFwiLi9hcHBsaWNhdGlvbi9xZ3JpZC90b2tlbi1zdWJzY3JpYmVyXCI7XG5pbXBvcnQgeyBlbnN1cmVUb2tlbnNUcmlnZ2VyIH0gZnJvbSBcIi4vYXBwbGljYXRpb24vcWdyaWQvdG9rZW4tdHJpZ2dlci1zZXR1cFwiO1xuaW1wb3J0IHsgQW50aHJvcGljRGlzcGF0Y2hlciB9IGZyb20gXCIuL3V0aWxzL3Byb3ZpZGVycy9hbnRocm9waWMvYW50aHJvcGljLWRpc3BhdGNoZXJcIjtcbmltcG9ydCB7IE9wZW5BSURpc3BhdGNoZXIgfSBmcm9tIFwiLi91dGlscy9wcm92aWRlcnMvb3BlbmFpL29wZW5haS1kaXNwYXRjaGVyXCI7XG5cbmNvbnN0IGhvc3QgPSBwcm9jZXNzLmVudi5IT1NUID8/IFwibG9jYWxob3N0XCI7XG5jb25zdCBwb3J0ID0gTnVtYmVyKHByb2Nlc3MuZW52LlBPUlQgPz8gNDQ5MDApO1xuXG5jb25zdCBjb25uQ29uZmlnID0ge1xuICBob3N0OiBwcm9jZXNzLmVudi5TT05BTVVfREJfSE9TVCA/PyBcImxvY2FsaG9zdFwiLFxuICBwb3J0OiBOdW1iZXIocHJvY2Vzcy5lbnYuU09OQU1VX0RCX1BPUlQgPz8gNTQzMiksXG4gIHVzZXI6IHByb2Nlc3MuZW52LlNPTkFNVV9EQl9VU0VSID8/IFwicG9zdGdyZXNcIixcbiAgcGFzc3dvcmQ6IHByb2Nlc3MuZW52LlNPTkFNVV9EQl9QQVNTV09SRCA/PyBcInBvc3RncmVzXCIsXG4gIGRhdGFiYXNlOiBwcm9jZXNzLmVudi5TT05BTVVfREJfTkFNRSA/PyBcInFncmlkXCIsXG59O1xuXG5leHBvcnQgZGVmYXVsdCBkZWZpbmVDb25maWcoe1xuICBwcm9qZWN0TmFtZTogcHJvY2Vzcy5lbnYuUFJPSkVDVF9OQU1FID8/IFwiUWdyaWRcIixcbiAgZGF0YWJhc2U6IHtcbiAgICBkZWZhdWx0T3B0aW9uczoge1xuICAgICAgY29ubmVjdGlvbjoge1xuICAgICAgICAuLi5jb25uQ29uZmlnLFxuICAgICAgICBrZWVwQWxpdmU6IHRydWUsXG4gICAgICAgIGtlZXBBbGl2ZUluaXRpYWxEZWxheU1pbGxpczogMTAwMDAsXG4gICAgICB9LFxuICAgIH0sXG4gIH0sXG4gIGFwaToge1xuICAgIGRpcjogXCJhcGlcIixcbiAgICB0aW1lem9uZTogXCJBc2lhL1Nlb3VsXCIsXG4gICAgcm91dGU6IHtcbiAgICAgIHByZWZpeDogXCIvYXBpXCIsXG4gICAgfSxcbiAgfSxcbiAgaTE4bjoge1xuICAgIGRlZmF1bHRMb2NhbGU6IFwia29cIixcbiAgICBzdXBwb3J0ZWRMb2NhbGVzOiBbXCJrb1wiLCBcImVuXCJdLFxuICB9LFxuICBzeW5jOiB7XG4gICAgdGFyZ2V0czogW1wid2ViXCJdLFxuICB9LFxuICB0ZXN0OiB7XG4gICAgcGFyYWxsZWw6IHRydWUsXG4gICAgbWF4V29ya2VyczogNCxcbiAgICBkZXZSdW5uZXI6IHsgZW5hYmxlZDogdHJ1ZSB9LFxuICB9LFxuICBsb2dnaW5nOiB7XG4gICAgc2lua3M6IHtcbiAgICAgIGNvbnNvbGU6IGdldENvbnNvbGVTaW5rKHtcbiAgICAgICAgZm9ybWF0dGVyOiBnZXRQcmV0dHlGb3JtYXR0ZXIoe1xuICAgICAgICAgIHRpbWVzdGFtcDogXCJ0aW1lXCIsXG4gICAgICAgICAgY2F0ZWdvcnlXaWR0aDogMjAsXG4gICAgICAgICAgY2F0ZWdvcnlUcnVuY2F0ZTogXCJtaWRkbGVcIixcbiAgICAgICAgfSksXG4gICAgICB9KSxcbiAgICAgIC8vIE1vbml0IO2DreyaqSBpbi1tZW1vcnkgcmluZyBidWZmZXIuIO2PrOunt+ydgCBzaW5rIOuzhCDigJQg7L2Y7IaUIOy2nOugpeydgCDqt7jrjIDroZzri6QuXG4gICAgICBtb25pdDogbW9uaXRMb2dTaW5rLFxuICAgIH0sXG4gICAgbG9nZ2VyczogW1xuICAgICAgLy8gcWdyaWQg66Gc6re4ICjsmpTssq0g67aE67CwLCBvYXV0aC91c2FnZSBBUEkpXG4gICAgICB7IGNhdGVnb3J5OiBbXCJxZ3JpZFwiXSwgc2lua3M6IFtcImNvbnNvbGVcIiwgXCJtb25pdFwiXSwgbG93ZXN0TGV2ZWw6IFwiaW5mb1wiIH0sXG4gICAgICAvLyBzb25hbXUg66Gc6re464qUIHdhcm5pbmcg7J207IOB66eMXG4gICAgICB7IGNhdGVnb3J5OiBbXCJzb25hbXVcIl0sIHNpbmtzOiBbXCJjb25zb2xlXCIsIFwibW9uaXRcIl0sIGxvd2VzdExldmVsOiBcIndhcm5pbmdcIiB9LFxuICAgICAgLy8gZmFzdGlmeSDroZzqt7gg7LCo64uoXG4gICAgICB7IGNhdGVnb3J5OiBbXCJmYXN0aWZ5XCJdLCBzaW5rczogW10sIGxvd2VzdExldmVsOiBcImZhdGFsXCIgfSxcbiAgICBdLFxuICB9LFxuICBzZXJ2ZXI6IHtcbiAgICBsaXN0ZW46IHsgcG9ydCwgaG9zdCB9LFxuICAgIGZhc3RpZnk6IHtcbiAgICAgIGJvZHlMaW1pdDogMTAgKiAxMDI0ICogMTAyNCxcbiAgICB9LFxuICAgIHBsdWdpbnM6IHtcbiAgICAgIGZvcm1ib2R5OiB0cnVlLFxuICAgICAgcXM6IHRydWUsXG4gICAgICBzc2U6IHRydWUsXG4gICAgICBtdWx0aXBhcnQ6IHsgbGltaXRzOiB7IGZpbGVTaXplOiAxMDI0ICogMTAyNCAqIDMwIH0gfSxcbiAgICAgIHN0YXRpYzoge1xuICAgICAgICByb290OiBwYXRoLmpvaW4oaW1wb3J0Lm1ldGEuZGlybmFtZSwgXCIvLi4vXCIsIFwicHVibGljXCIpLFxuICAgICAgICBwcmVmaXg6IFwiL2FwaS9wdWJsaWNcIixcbiAgICAgIH0sXG4gICAgICBjdXN0b206IChzZXJ2ZXIpID0+IHtcbiAgICAgICAgLy8gT0F1dGgg7L2c67CxIOKAlCBBbnRocm9waWPsnbQgL2NhbGxiYWNr7Jy866GcIOumrOuLpOydtOugie2KuFxuICAgICAgICBzZXJ2ZXIuZ2V0KFwiL2NhbGxiYWNrXCIsIGFzeW5jIChyZXF1ZXN0LCByZXBseSkgPT4ge1xuICAgICAgICAgIGNvbnN0IHsgY29kZSwgc3RhdGUgfSA9IHJlcXVlc3QucXVlcnkgYXMgeyBjb2RlPzogc3RyaW5nOyBzdGF0ZT86IHN0cmluZyB9O1xuICAgICAgICAgIGlmICghY29kZSB8fCAhc3RhdGUpIHtcbiAgICAgICAgICAgIHJldHVybiByZXBseS5yZWRpcmVjdChcIi8/b2F1dGg9ZXJyb3ImcmVhc29uPW1pc3NpbmdfcGFyYW1zXCIpO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgcmV0dXJuIFFncmlkRnJhbWUuaGFuZGxlT0F1dGhDYWxsYmFjayhjb2RlLCBzdGF0ZSwgcmVwbHkpO1xuICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIHJldHVybiByZXBseS5yZWRpcmVjdChcbiAgICAgICAgICAgICAgYC8/b2F1dGg9ZXJyb3ImcmVhc29uPSR7ZW5jb2RlVVJJQ29tcG9uZW50KChlIGFzIEVycm9yKS5tZXNzYWdlKX1gLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIE9wZW5BSSBPQXV0aCDripQgY29kZXggYXBwLXNlcnZlciDqsIAg7J6Q7LK0IGNhbGxiYWNrIOyEnOuyhOulvCDsmKzrprxcbiAgICAgICAgLy8gaGFuZGxlT3BlbkFJQ2FsbGJhY2sg67aI7ZWE7JqUIOKAlCBvYXV0aENvbXBsZXRlT3BlbkFJIEFQSSDroZwg7JmE66OMIO2ZleyduFxuICAgICAgfSxcbiAgICB9LFxuICAgIGFwaUNvbmZpZzoge1xuICAgICAgY29udGV4dFByb3ZpZGVyOiAoZGVmYXVsdENvbnRleHQsIHJlcXVlc3QpID0+IHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAuLi5kZWZhdWx0Q29udGV4dCxcbiAgICAgICAgICBpcDogcmVxdWVzdC5pcCxcbiAgICAgICAgICBib2R5OiByZXF1ZXN0LmJvZHksXG4gICAgICAgIH07XG4gICAgICB9LFxuICAgICAgZ3VhcmRIYW5kbGVyOiAoKSA9PiB7fSxcbiAgICAgIGNhY2hlQ29udHJvbEhhbmRsZXI6IChyZXEpID0+IHtcbiAgICAgICAgc3dpdGNoIChyZXEudHlwZSkge1xuICAgICAgICAgIGNhc2UgXCJhc3NldHNcIjpcbiAgICAgICAgICAgIC8vIEhhc2gg7Y+s7ZWo65CcIO2MjOydvDog7JiB6rWsIOy6kOyLnFxuICAgICAgICAgICAgaWYgKHJlcS5wYXRoLm1hdGNoKC8tW2EtZjAtOV0rXFwuLykpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIENhY2hlUHJlc2V0cy5pbW11dGFibGU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gQ2FjaGVQcmVzZXRzLmxvbmdMaXZlZDtcblxuICAgICAgICAgIGNhc2UgXCJhcGlcIjpcbiAgICAgICAgICAgIC8vIEdFVCDsmpTssq3rp4wg7LqQ7IuxIOqzoOugpFxuICAgICAgICAgICAgaWYgKHJlcS5tZXRob2QgPT09IFwiR0VUXCIpIHtcbiAgICAgICAgICAgICAgLy8g7Yq57KCVIOqyveuhnOuKlCDsp6fsnYAg7LqQ7IucXG4gICAgICAgICAgICAgIGlmIChyZXEucGF0aC5zdGFydHNXaXRoKFwiL2FwaS9zdGF0aWMtZGF0YVwiKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBDYWNoZVByZXNldHMuc2hvcnRMaXZlZDtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBpZiAocmVxLnBhdGguc3RhcnRzV2l0aChcIi9hcGkvdGVybXNcIikpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gQ2FjaGVQcmVzZXRzLm1lZGl1bUxpdmVkO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyDquLDrs7g6IOy6kOyLnCDsl4bsnYxcbiAgICAgICAgICAgIHJldHVybiBDYWNoZVByZXNldHMubm9DYWNoZTtcblxuICAgICAgICAgIGNhc2UgXCJzc3JcIjpcbiAgICAgICAgICAgIC8vIFNTUiDtjpjsnbTsp4A6IDEw7LSIIOy6kOyLnFxuICAgICAgICAgICAgcmV0dXJuIENhY2hlUHJlc2V0cy5zc3I7XG5cbiAgICAgICAgICBjYXNlIFwiY3NyXCI6XG4gICAgICAgICAgICAvLyBDU1IgZmFsbGJhY2sgKGluZGV4Lmh0bWwpOiAx67aEIOy6kOyLnFxuICAgICAgICAgICAgcmV0dXJuIENhY2hlUHJlc2V0cy5zaG9ydExpdmVkO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBDYWNoZVByZXNldHMubm9DYWNoZTtcbiAgICAgIH0sXG4gICAgfSxcbiAgICBjYWNoZToge1xuICAgICAgZGVmYXVsdDogXCJtYWluXCIsXG4gICAgICBzdG9yZXM6IHtcbiAgICAgICAgbWFpbjogc3RvcmUoKS51c2VMMUxheWVyKGNhY2hlRHJpdmVycy5tZW1vcnkoeyBtYXhTaXplOiBcIjUwbWJcIiB9KSksXG4gICAgICB9LFxuICAgICAgdHRsOiBcIjVtXCIsXG4gICAgICBwcmVmaXg6IFwiXCIsXG4gICAgfSxcbiAgICBsaWZlY3ljbGU6IHtcbiAgICAgIG9uU3RhcnQ6IGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3QgbG9nID0gZ2V0TG9nZ2VyKFtcInFncmlkXCIsIFwic3RhcnR1cFwiXSk7XG5cbiAgICAgICAgbGV0IHRyaWdnZXJSZWFkeSA9IHRydWU7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgYXdhaXQgZW5zdXJlVG9rZW5zVHJpZ2dlcihjb25uQ29uZmlnKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgIHRyaWdnZXJSZWFkeSA9IGZhbHNlO1xuICAgICAgICAgIGxvZy53YXJuKGB0cmlnZ2VyIHNldHVwIGZhaWxlZDogJHsoZSBhcyBFcnJvcikubWVzc2FnZX1gKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHN1YnNjcmliZXIgPSBuZXcgVG9rZW5TdWJzY3JpYmVyKGNvbm5Db25maWcsIFFncmlkRGlzcGF0Y2hlcik7XG4gICAgICAgIFFncmlkRGlzcGF0Y2hlci5zdWJzY3JpYmVyID0gc3Vic2NyaWJlcjtcblxuICAgICAgICBjb25zdCBzdGFydGVkID0gYXdhaXQgc3Vic2NyaWJlci5zdGFydCgpO1xuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3Qgb3BlbmFpRGlzcGF0Y2hlciA9IG5ldyBPcGVuQUlEaXNwYXRjaGVyKCk7XG4gICAgICAgICAgYXdhaXQgb3BlbmFpRGlzcGF0Y2hlci5zdGFydCgpO1xuICAgICAgICAgIFFncmlkRGlzcGF0Y2hlci5vcGVuYWlEaXNwYXRjaGVyID0gb3BlbmFpRGlzcGF0Y2hlcjtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgIGxvZy53YXJuKGBvcGVuYWkgZGlzcGF0Y2hlciBmYWlsZWQ6ICR7KGUgYXMgRXJyb3IpLm1lc3NhZ2V9YCk7XG4gICAgICAgIH1cblxuICAgICAgICB0cnkge1xuICAgICAgICAgIGNvbnN0IGFudGhyb3BpY0Rpc3BhdGNoZXIgPSBuZXcgQW50aHJvcGljRGlzcGF0Y2hlcigpO1xuICAgICAgICAgIGF3YWl0IGFudGhyb3BpY0Rpc3BhdGNoZXIuc3RhcnQoKTtcbiAgICAgICAgICBRZ3JpZERpc3BhdGNoZXIuYW50aHJvcGljRGlzcGF0Y2hlciA9IGFudGhyb3BpY0Rpc3BhdGNoZXI7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICBsb2cud2FybihgYW50aHJvcGljIGRpc3BhdGNoZXIgZmFpbGVkOiAkeyhlIGFzIEVycm9yKS5tZXNzYWdlfWApO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgYW50aHJvcGljQ291bnQgPSBRZ3JpZERpc3BhdGNoZXIuYW50aHJvcGljRGlzcGF0Y2hlcj8udG9rZW5Db3VudCA/PyAwO1xuICAgICAgICBjb25zdCBvcGVuYWlSZWFkeSA9IFFncmlkRGlzcGF0Y2hlci5vcGVuYWlEaXNwYXRjaGVyPy5yZWFkeVdvcmtlckNvdW50ID8/IDA7XG4gICAgICAgIGNvbnN0IG9wZW5haVRvdGFsID0gUWdyaWREaXNwYXRjaGVyLm9wZW5haURpc3BhdGNoZXI/LndvcmtlckNvdW50ID8/IDA7XG5cbiAgICAgICAgbG9nLmluZm8oYGxpc3RlbmluZyBvbiBodHRwOi8vJHtob3N0fToke3BvcnR9YCk7XG4gICAgICAgIGxvZy5pbmZvKGBhbnRocm9waWM6ICR7YW50aHJvcGljQ291bnR9IHRva2VucyByZWFkeWApO1xuICAgICAgICBsb2cuaW5mbyhgb3BlbmFpOiAke29wZW5haVJlYWR5fS8ke29wZW5haVRvdGFsfSB0b2tlbnMgcmVhZHlgKTtcbiAgICAgICAgbG9nLmluZm8oXG4gICAgICAgICAgYHN1YnNjcmliZXI6ICR7c3RhcnRlZCA/IFwiTElTVEVOIGFjdGl2ZVwiIDogXCJkZWdyYWRlZFwifSR7dHJpZ2dlclJlYWR5ID8gXCJcIiA6IFwiLCB0cmlnZ2VyIGZhaWxlZFwifWAsXG4gICAgICAgICk7XG4gICAgICB9LFxuICAgICAgb25TaHV0ZG93bjogYXN5bmMgKCkgPT4ge1xuICAgICAgICBjb25zdCBsb2cgPSBnZXRMb2dnZXIoW1wicWdyaWRcIiwgXCJzdGFydHVwXCJdKTtcbiAgICAgICAgaWYgKFFncmlkRGlzcGF0Y2hlci5vcGVuYWlEaXNwYXRjaGVyKSB7XG4gICAgICAgICAgYXdhaXQgUWdyaWREaXNwYXRjaGVyLm9wZW5haURpc3BhdGNoZXIuc3RvcCgpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChRZ3JpZERpc3BhdGNoZXIuYW50aHJvcGljRGlzcGF0Y2hlcikge1xuICAgICAgICAgIGF3YWl0IFFncmlkRGlzcGF0Y2hlci5hbnRocm9waWNEaXNwYXRjaGVyLnN0b3AoKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoUWdyaWREaXNwYXRjaGVyLnN1YnNjcmliZXIpIHtcbiAgICAgICAgICBhd2FpdCBRZ3JpZERpc3BhdGNoZXIuc3Vic2NyaWJlci5zdG9wKCk7XG4gICAgICAgIH1cbiAgICAgICAgbG9nLmluZm8oXCJncmFjZWZ1bCBzaHV0ZG93blwiKTtcbiAgICAgIH0sXG4gICAgICBvbkVycm9yOiAoZXJyb3IsIF9yZXF1ZXN0LCByZXBseSkgPT4ge1xuICAgICAgICBnZXRMb2dnZXIoW1wicWdyaWRcIl0pLmVycm9yKGAke2Vycm9yfWApO1xuICAgICAgICByZXBseS5zdGF0dXMoNTAwKS5zZW5kKHtcbiAgICAgICAgICBuYW1lOiBlcnJvci5uYW1lLFxuICAgICAgICAgIG1lc3NhZ2U6IGVycm9yLm1lc3NhZ2UsXG4gICAgICAgIH0pO1xuICAgICAgfSxcbiAgICB9LFxuICB9LFxufSk7XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7QUFnQkEsTUFBTSxPQUFPLFFBQVEsSUFBSSxRQUFRO0FBQ2pDLE1BQU0sT0FBTyxPQUFPLFFBQVEsSUFBSSxRQUFRLEtBQUs7QUFFN0MsTUFBTSxhQUFh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
183
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic29uYW11LmNvbmZpZy5qcyIsIm5hbWVzIjpbImNhY2hlRHJpdmVycyJdLCJzb3VyY2VzIjpbIi4uL3NyYy9zb25hbXUuY29uZmlnLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBwYXRoIGZyb20gXCJwYXRoXCI7XG5cbmltcG9ydCB7IGdldENvbnNvbGVTaW5rIH0gZnJvbSBcIkBsb2d0YXBlL2xvZ3RhcGVcIjtcbmltcG9ydCB7IGdldExvZ2dlciB9IGZyb20gXCJAbG9ndGFwZS9sb2d0YXBlXCI7XG5pbXBvcnQgeyBnZXRQcmV0dHlGb3JtYXR0ZXIgfSBmcm9tIFwiQGxvZ3RhcGUvcHJldHR5XCI7XG5pbXBvcnQgeyBDYWNoZVByZXNldHMsIGRlZmluZUNvbmZpZyB9IGZyb20gXCJzb25hbXVcIjtcbmltcG9ydCB7IGRyaXZlcnMgYXMgY2FjaGVEcml2ZXJzLCBzdG9yZSB9IGZyb20gXCJzb25hbXUvY2FjaGVcIjtcblxuaW1wb3J0IHsgbW9uaXRMb2dTaW5rIH0gZnJvbSBcIi4vYXBwbGljYXRpb24vbW9uaXQvbG9nLWJ1ZmZlclwiO1xuaW1wb3J0IHsgUWdyaWREaXNwYXRjaGVyIH0gZnJvbSBcIi4vYXBwbGljYXRpb24vcWdyaWQvcWdyaWQuZGlzcGF0Y2hlclwiO1xuaW1wb3J0IHsgUWdyaWRGcmFtZSB9IGZyb20gXCIuL2FwcGxpY2F0aW9uL3FncmlkL3FncmlkLmZyYW1lXCI7XG5pbXBvcnQgeyBUb2tlblN1YnNjcmliZXIgfSBmcm9tIFwiLi9hcHBsaWNhdGlvbi9xZ3JpZC90b2tlbi1zdWJzY3JpYmVyXCI7XG5pbXBvcnQgeyBlbnN1cmVUb2tlbnNUcmlnZ2VyIH0gZnJvbSBcIi4vYXBwbGljYXRpb24vcWdyaWQvdG9rZW4tdHJpZ2dlci1zZXR1cFwiO1xuaW1wb3J0IHsgaGFuZGxlU2VydmVyRXJyb3IgfSBmcm9tIFwiLi9zZXJ2ZXItZXJyb3ItaGFuZGxlclwiO1xuaW1wb3J0IHsgQW50aHJvcGljRGlzcGF0Y2hlciB9IGZyb20gXCIuL3V0aWxzL3Byb3ZpZGVycy9hbnRocm9waWMvYW50aHJvcGljLWRpc3BhdGNoZXJcIjtcbmltcG9ydCB7IE9wZW5BSURpc3BhdGNoZXIgfSBmcm9tIFwiLi91dGlscy9wcm92aWRlcnMvb3BlbmFpL29wZW5haS1kaXNwYXRjaGVyXCI7XG5cbmNvbnN0IGhvc3QgPSBwcm9jZXNzLmVudi5IT1NUID8/IFwibG9jYWxob3N0XCI7XG5jb25zdCBwb3J0ID0gTnVtYmVyKHByb2Nlc3MuZW52LlBPUlQgPz8gNDQ5MDApO1xuXG5jb25zdCBjb25uQ29uZmlnID0ge1xuICBob3N0OiBwcm9jZXNzLmVudi5TT05BTVVfREJfSE9TVCA/PyBcImxvY2FsaG9zdFwiLFxuICBwb3J0OiBOdW1iZXIocHJvY2Vzcy5lbnYuU09OQU1VX0RCX1BPUlQgPz8gNTQzMiksXG4gIHVzZXI6IHByb2Nlc3MuZW52LlNPTkFNVV9EQl9VU0VSID8/IFwicG9zdGdyZXNcIixcbiAgcGFzc3dvcmQ6IHByb2Nlc3MuZW52LlNPTkFNVV9EQl9QQVNTV09SRCA/PyBcInBvc3RncmVzXCIsXG4gIGRhdGFiYXNlOiBwcm9jZXNzLmVudi5TT05BTVVfREJfTkFNRSA/PyBcInFncmlkXCIsXG59O1xuXG5leHBvcnQgZGVmYXVsdCBkZWZpbmVDb25maWcoe1xuICBwcm9qZWN0TmFtZTogcHJvY2Vzcy5lbnYuUFJPSkVDVF9OQU1FID8/IFwiUWdyaWRcIixcbiAgZGF0YWJhc2U6IHtcbiAgICBkZWZhdWx0T3B0aW9uczoge1xuICAgICAgY29ubmVjdGlvbjoge1xuICAgICAgICAuLi5jb25uQ29uZmlnLFxuICAgICAgICBrZWVwQWxpdmU6IHRydWUsXG4gICAgICAgIGtlZXBBbGl2ZUluaXRpYWxEZWxheU1pbGxpczogMTAwMDAsXG4gICAgICB9LFxuICAgIH0sXG4gIH0sXG4gIGFwaToge1xuICAgIGRpcjogXCJhcGlcIixcbiAgICB0aW1lem9uZTogXCJBc2lhL1Nlb3VsXCIsXG4gICAgcm91dGU6IHtcbiAgICAgIHByZWZpeDogXCIvYXBpXCIsXG4gICAgfSxcbiAgfSxcbiAgaTE4bjoge1xuICAgIGRlZmF1bHRMb2NhbGU6IFwia29cIixcbiAgICBzdXBwb3J0ZWRMb2NhbGVzOiBbXCJrb1wiLCBcImVuXCJdLFxuICB9LFxuICBzeW5jOiB7XG4gICAgdGFyZ2V0czogW1wid2ViXCJdLFxuICB9LFxuICB0ZXN0OiB7XG4gICAgcGFyYWxsZWw6IHRydWUsXG4gICAgbWF4V29ya2VyczogNCxcbiAgICBkZXZSdW5uZXI6IHsgZW5hYmxlZDogdHJ1ZSB9LFxuICB9LFxuICBsb2dnaW5nOiB7XG4gICAgc2lua3M6IHtcbiAgICAgIGNvbnNvbGU6IGdldENvbnNvbGVTaW5rKHtcbiAgICAgICAgZm9ybWF0dGVyOiBnZXRQcmV0dHlGb3JtYXR0ZXIoe1xuICAgICAgICAgIHRpbWVzdGFtcDogXCJ0aW1lXCIsXG4gICAgICAgICAgY2F0ZWdvcnlXaWR0aDogMjAsXG4gICAgICAgICAgY2F0ZWdvcnlUcnVuY2F0ZTogXCJtaWRkbGVcIixcbiAgICAgICAgfSksXG4gICAgICB9KSxcbiAgICAgIC8vIE1vbml0IO2DreyaqSBpbi1tZW1vcnkgcmluZyBidWZmZXIuIO2PrOunt+ydgCBzaW5rIOuzhCDigJQg7L2Y7IaUIOy2nOugpeydgCDqt7jrjIDroZzri6QuXG4gICAgICBtb25pdDogbW9uaXRMb2dTaW5rLFxuICAgIH0sXG4gICAgbG9nZ2VyczogW1xuICAgICAgLy8gcWdyaWQg66Gc6re4ICjsmpTssq0g67aE67CwLCBvYXV0aC91c2FnZSBBUEkpXG4gICAgICB7IGNhdGVnb3J5OiBbXCJxZ3JpZFwiXSwgc2lua3M6IFtcImNvbnNvbGVcIiwgXCJtb25pdFwiXSwgbG93ZXN0TGV2ZWw6IFwiaW5mb1wiIH0sXG4gICAgICAvLyBzb25hbXUg66Gc6re464qUIHdhcm5pbmcg7J207IOB66eMXG4gICAgICB7IGNhdGVnb3J5OiBbXCJzb25hbXVcIl0sIHNpbmtzOiBbXCJjb25zb2xlXCIsIFwibW9uaXRcIl0sIGxvd2VzdExldmVsOiBcIndhcm5pbmdcIiB9LFxuICAgICAgLy8gZmFzdGlmeSDroZzqt7gg7LCo64uoXG4gICAgICB7IGNhdGVnb3J5OiBbXCJmYXN0aWZ5XCJdLCBzaW5rczogW10sIGxvd2VzdExldmVsOiBcImZhdGFsXCIgfSxcbiAgICBdLFxuICB9LFxuICBzZXJ2ZXI6IHtcbiAgICBsaXN0ZW46IHsgcG9ydCwgaG9zdCB9LFxuICAgIGZhc3RpZnk6IHtcbiAgICAgIGJvZHlMaW1pdDogMTAgKiAxMDI0ICogMTAyNCxcbiAgICB9LFxuICAgIHBsdWdpbnM6IHtcbiAgICAgIGZvcm1ib2R5OiB0cnVlLFxuICAgICAgcXM6IHRydWUsXG4gICAgICBzc2U6IHRydWUsXG4gICAgICBtdWx0aXBhcnQ6IHsgbGltaXRzOiB7IGZpbGVTaXplOiAxMDI0ICogMTAyNCAqIDMwIH0gfSxcbiAgICAgIHN0YXRpYzoge1xuICAgICAgICByb290OiBwYXRoLmpvaW4oaW1wb3J0Lm1ldGEuZGlybmFtZSwgXCIvLi4vXCIsIFwicHVibGljXCIpLFxuICAgICAgICBwcmVmaXg6IFwiL2FwaS9wdWJsaWNcIixcbiAgICAgIH0sXG4gICAgICBjdXN0b206IChzZXJ2ZXIpID0+IHtcbiAgICAgICAgLy8gT0F1dGgg7L2c67CxIOKAlCBBbnRocm9waWPsnbQgL2NhbGxiYWNr7Jy866GcIOumrOuLpOydtOugie2KuFxuICAgICAgICBzZXJ2ZXIuZ2V0KFwiL2NhbGxiYWNrXCIsIGFzeW5jIChyZXF1ZXN0LCByZXBseSkgPT4ge1xuICAgICAgICAgIGNvbnN0IHsgY29kZSwgc3RhdGUgfSA9IHJlcXVlc3QucXVlcnkgYXMgeyBjb2RlPzogc3RyaW5nOyBzdGF0ZT86IHN0cmluZyB9O1xuICAgICAgICAgIGlmICghY29kZSB8fCAhc3RhdGUpIHtcbiAgICAgICAgICAgIHJldHVybiByZXBseS5yZWRpcmVjdChcIi8/b2F1dGg9ZXJyb3ImcmVhc29uPW1pc3NpbmdfcGFyYW1zXCIpO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgcmV0dXJuIFFncmlkRnJhbWUuaGFuZGxlT0F1dGhDYWxsYmFjayhjb2RlLCBzdGF0ZSwgcmVwbHkpO1xuICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIHJldHVybiByZXBseS5yZWRpcmVjdChcbiAgICAgICAgICAgICAgYC8/b2F1dGg9ZXJyb3ImcmVhc29uPSR7ZW5jb2RlVVJJQ29tcG9uZW50KChlIGFzIEVycm9yKS5tZXNzYWdlKX1gLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIE9wZW5BSSBPQXV0aCDripQgY29kZXggYXBwLXNlcnZlciDqsIAg7J6Q7LK0IGNhbGxiYWNrIOyEnOuyhOulvCDsmKzrprxcbiAgICAgICAgLy8gaGFuZGxlT3BlbkFJQ2FsbGJhY2sg67aI7ZWE7JqUIOKAlCBvYXV0aENvbXBsZXRlT3BlbkFJIEFQSSDroZwg7JmE66OMIO2ZleyduFxuICAgICAgfSxcbiAgICB9LFxuICAgIGFwaUNvbmZpZzoge1xuICAgICAgY29udGV4dFByb3ZpZGVyOiAoZGVmYXVsdENvbnRleHQsIHJlcXVlc3QpID0+IHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAuLi5kZWZhdWx0Q29udGV4dCxcbiAgICAgICAgICBpcDogcmVxdWVzdC5pcCxcbiAgICAgICAgICBib2R5OiByZXF1ZXN0LmJvZHksXG4gICAgICAgIH07XG4gICAgICB9LFxuICAgICAgZ3VhcmRIYW5kbGVyOiAoKSA9PiB7fSxcbiAgICAgIGNhY2hlQ29udHJvbEhhbmRsZXI6IChyZXEpID0+IHtcbiAgICAgICAgc3dpdGNoIChyZXEudHlwZSkge1xuICAgICAgICAgIGNhc2UgXCJhc3NldHNcIjpcbiAgICAgICAgICAgIC8vIEhhc2gg7Y+s7ZWo65CcIO2MjOydvDog7JiB6rWsIOy6kOyLnFxuICAgICAgICAgICAgaWYgKHJlcS5wYXRoLm1hdGNoKC8tW2EtZjAtOV0rXFwuLykpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIENhY2hlUHJlc2V0cy5pbW11dGFibGU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gQ2FjaGVQcmVzZXRzLmxvbmdMaXZlZDtcblxuICAgICAgICAgIGNhc2UgXCJhcGlcIjpcbiAgICAgICAgICAgIC8vIEdFVCDsmpTssq3rp4wg7LqQ7IuxIOqzoOugpFxuICAgICAgICAgICAgaWYgKHJlcS5tZXRob2QgPT09IFwiR0VUXCIpIHtcbiAgICAgICAgICAgICAgLy8g7Yq57KCVIOqyveuhnOuKlCDsp6fsnYAg7LqQ7IucXG4gICAgICAgICAgICAgIGlmIChyZXEucGF0aC5zdGFydHNXaXRoKFwiL2FwaS9zdGF0aWMtZGF0YVwiKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBDYWNoZVByZXNldHMuc2hvcnRMaXZlZDtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBpZiAocmVxLnBhdGguc3RhcnRzV2l0aChcIi9hcGkvdGVybXNcIikpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gQ2FjaGVQcmVzZXRzLm1lZGl1bUxpdmVkO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyDquLDrs7g6IOy6kOyLnCDsl4bsnYxcbiAgICAgICAgICAgIHJldHVybiBDYWNoZVByZXNldHMubm9DYWNoZTtcblxuICAgICAgICAgIGNhc2UgXCJzc3JcIjpcbiAgICAgICAgICAgIC8vIFNTUiDtjpjsnbTsp4A6IDEw7LSIIOy6kOyLnFxuICAgICAgICAgICAgcmV0dXJuIENhY2hlUHJlc2V0cy5zc3I7XG5cbiAgICAgICAgICBjYXNlIFwiY3NyXCI6XG4gICAgICAgICAgICAvLyBDU1IgZmFsbGJhY2sgKGluZGV4Lmh0bWwpOiAx67aEIOy6kOyLnFxuICAgICAgICAgICAgcmV0dXJuIENhY2hlUHJlc2V0cy5zaG9ydExpdmVkO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBDYWNoZVByZXNldHMubm9DYWNoZTtcbiAgICAgIH0sXG4gICAgfSxcbiAgICBjYWNoZToge1xuICAgICAgZGVmYXVsdDogXCJtYWluXCIsXG4gICAgICBzdG9yZXM6IHtcbiAgICAgICAgbWFpbjogc3RvcmUoKS51c2VMMUxheWVyKGNhY2hlRHJpdmVycy5tZW1vcnkoeyBtYXhTaXplOiBcIjUwbWJcIiB9KSksXG4gICAgICB9LFxuICAgICAgdHRsOiBcIjVtXCIsXG4gICAgICBwcmVmaXg6IFwiXCIsXG4gICAgfSxcbiAgICBsaWZlY3ljbGU6IHtcbiAgICAgIG9uU3RhcnQ6IGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3QgbG9nID0gZ2V0TG9nZ2VyKFtcInFncmlkXCIsIFwic3RhcnR1cFwiXSk7XG5cbiAgICAgICAgbGV0IHRyaWdnZXJSZWFkeSA9IHRydWU7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgYXdhaXQgZW5zdXJlVG9rZW5zVHJpZ2dlcihjb25uQ29uZmlnKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgIHRyaWdnZXJSZWFkeSA9IGZhbHNlO1xuICAgICAgICAgIGxvZy53YXJuKGB0cmlnZ2VyIHNldHVwIGZhaWxlZDogJHsoZSBhcyBFcnJvcikubWVzc2FnZX1gKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHN1YnNjcmliZXIgPSBuZXcgVG9rZW5TdWJzY3JpYmVyKGNvbm5Db25maWcsIFFncmlkRGlzcGF0Y2hlcik7XG4gICAgICAgIFFncmlkRGlzcGF0Y2hlci5zdWJzY3JpYmVyID0gc3Vic2NyaWJlcjtcblxuICAgICAgICBjb25zdCBzdGFydGVkID0gYXdhaXQgc3Vic2NyaWJlci5zdGFydCgpO1xuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3Qgb3BlbmFpRGlzcGF0Y2hlciA9IG5ldyBPcGVuQUlEaXNwYXRjaGVyKCk7XG4gICAgICAgICAgYXdhaXQgb3BlbmFpRGlzcGF0Y2hlci5zdGFydCgpO1xuICAgICAgICAgIFFncmlkRGlzcGF0Y2hlci5vcGVuYWlEaXNwYXRjaGVyID0gb3BlbmFpRGlzcGF0Y2hlcjtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgIGxvZy53YXJuKGBvcGVuYWkgZGlzcGF0Y2hlciBmYWlsZWQ6ICR7KGUgYXMgRXJyb3IpLm1lc3NhZ2V9YCk7XG4gICAgICAgIH1cblxuICAgICAgICB0cnkge1xuICAgICAgICAgIGNvbnN0IGFudGhyb3BpY0Rpc3BhdGNoZXIgPSBuZXcgQW50aHJvcGljRGlzcGF0Y2hlcigpO1xuICAgICAgICAgIGF3YWl0IGFudGhyb3BpY0Rpc3BhdGNoZXIuc3RhcnQoKTtcbiAgICAgICAgICBRZ3JpZERpc3BhdGNoZXIuYW50aHJvcGljRGlzcGF0Y2hlciA9IGFudGhyb3BpY0Rpc3BhdGNoZXI7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICBsb2cud2FybihgYW50aHJvcGljIGRpc3BhdGNoZXIgZmFpbGVkOiAkeyhlIGFzIEVycm9yKS5tZXNzYWdlfWApO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgYW50aHJvcGljQ291bnQgPSBRZ3JpZERpc3BhdGNoZXIuYW50aHJvcGljRGlzcGF0Y2hlcj8udG9rZW5Db3VudCA/PyAwO1xuICAgICAgICBjb25zdCBvcGVuYWlSZWFkeSA9IFFncmlkRGlzcGF0Y2hlci5vcGVuYWlEaXNwYXRjaGVyPy5yZWFkeVdvcmtlckNvdW50ID8/IDA7XG4gICAgICAgIGNvbnN0IG9wZW5haVRvdGFsID0gUWdyaWREaXNwYXRjaGVyLm9wZW5haURpc3BhdGNoZXI/LndvcmtlckNvdW50ID8/IDA7XG5cbiAgICAgICAgbG9nLmluZm8oYGxpc3RlbmluZyBvbiBodHRwOi8vJHtob3N0fToke3BvcnR9YCk7XG4gICAgICAgIGxvZy5pbmZvKGBhbnRocm9waWM6ICR7YW50aHJvcGljQ291bnR9IHRva2VucyByZWFkeWApO1xuICAgICAgICBsb2cuaW5mbyhgb3BlbmFpOiAke29wZW5haVJlYWR5fS8ke29wZW5haVRvdGFsfSB0b2tlbnMgcmVhZHlgKTtcbiAgICAgICAgbG9nLmluZm8oXG4gICAgICAgICAgYHN1YnNjcmliZXI6ICR7c3RhcnRlZCA/IFwiTElTVEVOIGFjdGl2ZVwiIDogXCJkZWdyYWRlZFwifSR7dHJpZ2dlclJlYWR5ID8gXCJcIiA6IFwiLCB0cmlnZ2VyIGZhaWxlZFwifWAsXG4gICAgICAgICk7XG4gICAgICB9LFxuICAgICAgb25TaHV0ZG93bjogYXN5bmMgKCkgPT4ge1xuICAgICAgICBjb25zdCBsb2cgPSBnZXRMb2dnZXIoW1wicWdyaWRcIiwgXCJzdGFydHVwXCJdKTtcbiAgICAgICAgaWYgKFFncmlkRGlzcGF0Y2hlci5vcGVuYWlEaXNwYXRjaGVyKSB7XG4gICAgICAgICAgYXdhaXQgUWdyaWREaXNwYXRjaGVyLm9wZW5haURpc3BhdGNoZXIuc3RvcCgpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChRZ3JpZERpc3BhdGNoZXIuYW50aHJvcGljRGlzcGF0Y2hlcikge1xuICAgICAgICAgIGF3YWl0IFFncmlkRGlzcGF0Y2hlci5hbnRocm9waWNEaXNwYXRjaGVyLnN0b3AoKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoUWdyaWREaXNwYXRjaGVyLnN1YnNjcmliZXIpIHtcbiAgICAgICAgICBhd2FpdCBRZ3JpZERpc3BhdGNoZXIuc3Vic2NyaWJlci5zdG9wKCk7XG4gICAgICAgIH1cbiAgICAgICAgbG9nLmluZm8oXCJncmFjZWZ1bCBzaHV0ZG93blwiKTtcbiAgICAgIH0sXG4gICAgICBvbkVycm9yOiAoZXJyb3IsIF9yZXF1ZXN0LCByZXBseSkgPT4ge1xuICAgICAgICBoYW5kbGVTZXJ2ZXJFcnJvcihlcnJvciwgcmVwbHkpO1xuICAgICAgfSxcbiAgICB9LFxuICB9LFxufSk7XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7O0FBaUJBLE1BQU0sT0FBTyxRQUFRLElBQUksUUFBUTtBQUNqQyxNQUFNLE9BQU8sT0FBTyxRQUFRLElBQUksUUFBUSxLQUFLO0FBRTdDLE1BQU0sYUFBYTtDQUNqQixNQUFNLFFBQVEsSUFBSSxrQkFBa0I7Q0FDcEMsTUFBTSxPQUFPLFFBQVEsSUFBSSxr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