@cartanova/qgrid-cli 2.10.0 → 2.10.1

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 (69) hide show
  1. package/bundle/dist/application/qgrid/conv-routing.js +4 -14
  2. package/bundle/dist/application/qgrid/qgrid.dispatcher.js +10 -5
  3. package/bundle/dist/application/request-log/request-log.model.js +14 -12
  4. package/bundle/dist/application/request-log-step/request-log-step.model.js +7 -11
  5. package/bundle/dist/application/setting/setting.model.js +13 -27
  6. package/bundle/dist/application/token/token.model.js +52 -47
  7. package/bundle/dist/server-error-handler.js +1 -1
  8. package/bundle/dist/sonamu.config.js +3 -15
  9. package/bundle/dist/utils/providers/anthropic/anthropic-constants.js +4 -2
  10. package/bundle/dist/utils/providers/common/model-cost.js +10 -3
  11. package/bundle/src/application/qgrid/conv-routing.test.ts +0 -32
  12. package/bundle/src/application/qgrid/conv-routing.ts +7 -26
  13. package/bundle/src/application/qgrid/qgrid.dispatcher.test.ts +65 -121
  14. package/bundle/src/application/qgrid/qgrid.dispatcher.ts +12 -6
  15. package/bundle/src/application/qgrid/qgrid.frame.test.ts +10 -24
  16. package/bundle/src/application/request-log/request-log.model.test.ts +37 -2
  17. package/bundle/src/application/request-log/request-log.model.ts +14 -7
  18. package/bundle/src/application/request-log-step/request-log-step.model.ts +3 -15
  19. package/bundle/src/application/setting/setting.constant.test.ts +1 -13
  20. package/bundle/src/application/setting/setting.model.ts +10 -26
  21. package/bundle/src/application/setting/setting.persistence.test.ts +27 -0
  22. package/bundle/src/application/token/token.model.test.ts +86 -19
  23. package/bundle/src/application/token/token.model.ts +59 -44
  24. package/bundle/src/server-error-handler.ts +1 -2
  25. package/bundle/src/sonamu.config.ts +4 -31
  26. package/bundle/src/utils/providers/anthropic/anthropic-constants.test.ts +6 -1
  27. package/bundle/src/utils/providers/anthropic/anthropic-constants.ts +5 -2
  28. package/bundle/src/utils/providers/anthropic/anthropic-dispatcher.test.ts +1 -26
  29. package/bundle/src/utils/providers/common/model-cost.test.ts +22 -1
  30. package/bundle/src/utils/providers/common/model-cost.ts +22 -5
  31. package/bundle/src/utils/providers/common/provider-dispatcher.ts +4 -11
  32. package/bundle/web-dist/client/assets/index-Cq4_ExLO.js +106 -0
  33. package/bundle/web-dist/client/assets/logs-kg1KOMBk.js +1 -0
  34. package/bundle/web-dist/client/assets/{monit-DrYZkisv.js → monit-DmtHTmSM.js} +1 -1
  35. package/bundle/web-dist/client/assets/{routes-C8Y6olae.js → routes-CXotE1OF.js} +1 -1
  36. package/bundle/web-dist/client/assets/services.generated-Cbvg2sGQ.js +51 -0
  37. package/bundle/web-dist/client/assets/{settings-CdVqtDQ5.js → settings-CfJDz4AC.js} +1 -1
  38. package/bundle/web-dist/client/assets/show-gBpWK4z2.js +2 -0
  39. package/bundle/web-dist/client/assets/{tokens-CxXtdk9o.js → tokens-CbFJjIyC.js} +1 -1
  40. package/bundle/web-dist/client/assets/use-oauth-login-flow-jJo7GV3r.js +1 -0
  41. package/bundle/web-dist/client/assets/{use-update-token-mutation-Dkv_HG-C.js → use-update-token-mutation-D-Y8OySK.js} +1 -1
  42. package/bundle/web-dist/client/index.html +2 -2
  43. package/bundle/web-dist/server/assets/{lazyRouteComponent-DyizoQKi.js → lazyRouteComponent-Bj1cPq6x.js} +2 -2
  44. package/bundle/web-dist/server/assets/{logs-DO8zBdBR.js → logs-DMlOXcDS.js} +20 -12
  45. package/bundle/web-dist/server/assets/{monit-COH4MckI.js → monit-Dg1wZCdx.js} +3 -3
  46. package/bundle/web-dist/server/assets/{plus-C1D8z9o0.js → plus-DVobMrag.js} +1 -1
  47. package/bundle/web-dist/server/assets/{react-dom-PfWvArTX.js → react-dom-BjR1Iaz8.js} +1 -1
  48. package/bundle/web-dist/server/assets/{routes-Btja-741.js → routes-C7lB2Q85.js} +5 -5
  49. package/bundle/web-dist/server/assets/{services.generated-BsKOUSXl.js → services.generated-BM4X3Ecj.js} +102 -6
  50. package/bundle/web-dist/server/assets/{settings-DPcWGvy-.js → settings-BaIBt_Vs.js} +4 -4
  51. package/bundle/web-dist/server/assets/{show-CMXbb3TJ.js → show-CDxGr4rS.js} +9 -8
  52. package/bundle/web-dist/server/assets/{tokens-DAUmTrgO.js → tokens-DJlfeGcx.js} +5 -5
  53. package/bundle/web-dist/server/assets/{use-oauth-login-flow-GsGwqefs.js → use-oauth-login-flow-DYKnG4A2.js} +32 -15
  54. package/bundle/web-dist/server/assets/{use-update-token-mutation-RujWERvj.js → use-update-token-mutation-DqGMopII.js} +1 -1
  55. package/bundle/web-dist/server/entry-server.generated.js +381 -21
  56. package/package.json +1 -1
  57. package/skills/qgrid/references/ai-sdk-provider-contract.md +4 -2
  58. package/skills/qgrid/references/anthropic-claude-code-runtime.md +3 -2
  59. package/skills/qgrid/references/request-log-run-lifecycle.md +2 -0
  60. package/skills/qgrid/references/sonamu-api-web-flow.md +1 -1
  61. package/skills/qgrid/references/token-auth-quota-lifecycle.md +2 -0
  62. package/skills/qgrid/references/verification-and-debugging.md +24 -13
  63. package/bundle/dist/utils/providers/common/token-picker.js +0 -14
  64. package/bundle/src/utils/providers/common/token-picker.ts +0 -18
  65. package/bundle/web-dist/client/assets/index-BfwrIBHs.js +0 -106
  66. package/bundle/web-dist/client/assets/logs-Brit-LqB.js +0 -1
  67. package/bundle/web-dist/client/assets/services.generated-Bg2XkD-D.js +0 -51
  68. package/bundle/web-dist/client/assets/show-2B2X9MkO.js +0 -2
  69. package/bundle/web-dist/client/assets/use-oauth-login-flow-B9EqnwY9.js +0 -1
@@ -34,6 +34,7 @@ const ONE_MILLION_CONTEXT_MODELS = /* @__PURE__ */ new Set([
34
34
  "claude-opus-5-5",
35
35
  "claude-sonnet-5-5",
36
36
  "claude-sonnet-5",
37
+ "claude-haiku-5-5",
37
38
  "claude-sonnet-4-6",
38
39
  "claude-opus-4-6",
39
40
  "claude-opus-4-8"
@@ -44,7 +45,8 @@ const ADAPTIVE_THINKING_MODELS = /* @__PURE__ */ new Set([
44
45
  "claude-fable-5",
45
46
  "claude-opus-5",
46
47
  "claude-opus-5-5",
47
- "claude-sonnet-5-5"
48
+ "claude-sonnet-5-5",
49
+ "claude-haiku-5-5"
48
50
  ]);
49
51
  const FABLE_FAMILY_MODELS = /* @__PURE__ */ new Set(["claude-fable-5-1", "claude-fable-5"]);
50
52
  for (const model of CLI_ONE_MILLION_SUFFIX_MODELS) if (!ONE_MILLION_CONTEXT_MODELS.has(model)) throw new Error(`[invariant] CLI 1M suffix model not in context set: ${model}`);
@@ -68,4 +70,4 @@ function assertSupportedOneMillionSuffix(model) {
68
70
  //#endregion
69
71
  export { ANTHROPIC_CLAUDE_CWD, ANTHROPIC_CONFIG_DIR_BASE, ANTHROPIC_DEFAULT_EFFORT, ANTHROPIC_DEFAULT_MODEL, ANTHROPIC_DISALLOWED_TOOLS, anthropicConfigDir, assertSupportedOneMillionSuffix, canonicalAnthropicModel, hasOneMillionSuffix, isFableFamilyModel, needsCli1mSuffix, supports1MContext, usesAdaptiveThinking };
70
72
 
71
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYW50aHJvcGljLWNvbnN0YW50cy5qcyIsIm5hbWVzIjpbXSwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvdXRpbHMvcHJvdmlkZXJzL2FudGhyb3BpYy9hbnRocm9waWMtY29uc3RhbnRzLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQW50aHJvcGljKENsYXVkZSkgcHJvdmlkZXIg7IOB7IiYLlxuICpcbiAqIENsYXVkZSBDb2RlIENMSSDtlIzrnpjqt7gvZW52IOqzhOyVveydhCBBbnRocm9waWMgZGlzcGF0Y2hlciDsmqnsnLzroZwg6rOg7KCV7ZWc64ukOlxuICogIC0gYC0tbm8tc2Vzc2lvbi1wZXJzaXN0ZW5jZWAg7KCc6rGwICjrqYDti7DthLQg7ZWE7IiYKS5cbiAqICAtIGAtLWlucHV0LWZvcm1hdCBzdHJlYW0tanNvbmAg7LaU6rCAIChzdGRpbiDsnLzroZwg7J6F66ClIOyWtOuMke2EsCBKU09OTCDtnZjrprwpLlxuICogIC0gQW50aHJvcGljIOqyveuhnOuKlCDrp6Qg7Zi47LacIGAtLXNlc3Npb24taWRgIOuhnCBmcmVzaCBzZXNzaW9uIOydhCDrsJzquIntlZzri6QuXG4gKi9cblxuLy8gQ0MgLS1tb2RlbCDtlIzrnpjqt7jqsIAg67Cb64qUIG9mZmljaWFsIG1vZGVsIGlkIChhbGlhcyBcInNvbm5ldFwiIOqwgCDslYTri4jrnbwg7KCV7ZmV7ZWcIOyLneuzhOyekOuhnCDqs6DsoJUpLlxuLy8gY2xhdWRlLWFwaSDsiqTtgqwg7ZmV7J24OiBTb25uZXQgNC42IG9mZmljaWFsIGlkID0gXCJjbGF1ZGUtc29ubmV0LTQtNlwiICjrgqDsp5wgc3VmZml4IOyXhuydjCkuXG4vLyBtb2RlbC1jb3N0IO2FjOydtOu4lOyXkOuPhCBcImNsYXVkZS1zb25uZXQtNC02XCIg7YKkIOyhtOyerFxuZXhwb3J0IGNvbnN0IEFOVEhST1BJQ19ERUZBVUxUX01PREVMID0gXCJjbGF1ZGUtc29ubmV0LTQtNlwiO1xuLy8gT3BlbkFJIHByb3ZpZGVyIOq4sOuzuOqwkihvcGVuYWktZGlzcGF0Y2hlciBERUZBVUxUX0VGRk9SVCnqs7wg66ee7LaY64ukLiDtgbTrnbzqsIAgZWZmb3J0IOuvuOyngOyglSDsi5wg7JWI7KCE66edLlxuZXhwb3J0IGNvbnN0IEFOVEhST1BJQ19ERUZBVUxUX0VGRk9SVCA9IFwibG93XCI7XG4vLyBwcm9qZWN0IHNjb3BlIGN3ZCAoc2V0dGluZ3MuanNvbiDqsqnrpqwpLiDthqDtgbDrs4Qg6rKp66as64qUIENMQVVERV9DT05GSUdfRElSIOuhnCDtlZzri6QuXG5leHBvcnQgY29uc3QgQU5USFJPUElDX0NMQVVERV9DV0QgPSBcIi90bXAvcWdyaWQtYW50aHJvcGljXCI7XG4vLyBwZXItdG9rZW4gQ0xBVURFX0NPTkZJR19ESVIg7J2YIOuyoOydtOyKpC4g7Iuk7KCcIOqyveuhnOuKlCBgJHtCQVNFfS8ke3Rva2VuSWR9YCAoUjEwIOqyqeumrCkuXG5leHBvcnQgY29uc3QgQU5USFJPUElDX0NPTkZJR19ESVJfQkFTRSA9IFwiL3RtcC9xZ3JpZC1hbnRocm9waWMtY29uZmlnXCI7XG4vLyBDQyDqsIAg7J6Q64+ZIO2ZnOyEse2ZlO2VmOuKlCBkZWZlcnJlZCDrj4Tqtawg4oCUIO2GoO2BsCDstZzsoIHtmZQg7JyE7ZW0IGRpc3BhdGNoZXIg6rK966Gc7JeQ7IScIOywqOuLqC5cbmV4cG9ydCBjb25zdCBBTlRIUk9QSUNfRElTQUxMT1dFRF9UT09MUyA9IFtcIk1vbml0b3JcIiwgXCJQdXNoTm90aWZpY2F0aW9uXCIsIFwiUmVtb3RlVHJpZ2dlclwiXSBhcyBjb25zdDtcbmNvbnN0IE9ORV9NSUxMSU9OX1NVRkZJWF9SRSA9IC9cXFsxbVxcXSQvaTtcblxuLy8g7Yag7YGw67OEIENMQVVERV9DT05GSUdfRElSIOqyveuhnCDqt5zsuZkoUjEwIOqyqeumrCDqs4Tslb0pLiB0b2tlbklkIOuzhOuhnCDrtoTrpqzrkJjslrQsIOqwmeydgCBjbGF1ZGUgc2Vzc2lvbi1pZFxuLy8g652864+EIOuLpOuluCDthqDtgbDsnbTrqbQg64uk66W4IGNvbmZpZyBkaXIg4oaSIHRyYW5zY3JpcHQg6rCAIOyEnuydtOyngCDslYrripTri6QuIOu2gOyImO2aqOqzvCDsl4bripQg7Iic7IiYIO2VqOyImOudvFxuLy8g6rKp66asIOqzhOyVveydhCDri6jsnIQg7YWM7Iqk7Yq466GcIOqzoOygle2VoCDsiJgg7J6I64ukKFU2IFIxMCDqtazsobAg6rKA7KadKS4g7Iuk7KCcIGRpciDsg53shLHsnYAgZW5zdXJlQ29uZmlnRGlyIOqwgCDtlZzri6QuXG5leHBvcnQgZnVuY3Rpb24gYW50aHJvcGljQ29uZmlnRGlyKHRva2VuSWQ6IG51bWJlcik6IHN0cmluZyB7XG4gIHJldHVybiBgJHtBTlRIUk9QSUNfQ09ORklHX0RJUl9CQVNFfS8ke3Rva2VuSWR9YDtcbn1cblxuLy8gbW9kZWwgaWQg66W8IGNhbm9uaWNhbChwcm92aWRlciBwcmVmaXgg7JeG64qUIENMSS9jb3N0IO2CpCkg66GcIOygleq3nO2ZlFxuLy8gYWktc2RrIOuKlCAnYW50aHJvcGljL2NsYXVkZS0qJyDtmJXtg5zroZwg67O064K064qU642wLCBwcmVmaXgg6rCAIGNhbGN1bGF0ZUNvc3RVc2Qg7JeQIOyDiOuptCBjb3N0IOqwgFxuLy8gZGVmYXVsdCDri6jqsIDroZwg7Jik6rOE7IKw65Cc64ukLiBgWzFtXWAgc3VmZml4IOuPhCBDTEkgZW1pdCDsoITsmqnsnbTrnbxcbi8vIGJhc2UgY2Fub25pY2FsIOyXkOyEnOuKlCDsoJzqsbDtlZzri6QuIOuvuOyngOygleydtOuptCBkZWZhdWx0LlxuZXhwb3J0IGZ1bmN0aW9uIGNhbm9uaWNhbEFudGhyb3BpY01vZGVsKG1vZGVsPzogc3RyaW5nKTogc3RyaW5nIHtcbiAgY29uc3QgcmF3ID0gbW9kZWwgfHwgQU5USFJPUElDX0RFRkFVTFRfTU9ERUw7XG4gIGNvbnN0IHdpdGhvdXRQcm92aWRlciA9IHJhdy5pbmNsdWRlcyhcIi9cIikgPyByYXcuc3BsaXQoXCIvXCIpLnBvcCgpISA6IHJhdztcbiAgcmV0dXJuIHdpdGhvdXRQcm92aWRlci5yZXBsYWNlKE9ORV9NSUxMSU9OX1NVRkZJWF9SRSwgXCJcIik7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBoYXNPbmVNaWxsaW9uU3VmZml4KG1vZGVsPzogc3RyaW5nKTogYm9vbGVhbiB7XG4gIHJldHVybiBtb2RlbCAhPT0gdW5kZWZpbmVkICYmIE9ORV9NSUxMSU9OX1NVRkZJWF9SRS50ZXN0KG1vZGVsKTtcbn1cblxuLy8gMU0g7KeA7JuQIOyXrOu2gOuKlCBDbGF1ZGUgQ29kZSDrgrTrtoDsnZgg6rSR67KU7JyE7ZWcIHByZWZpeCDtjJDsoJXsnbQg7JWE64uI6528IHFncmlk7JeQ7IScIO2ZleyduO2VnCBleGFjdCBzZXQg7Jy866GcXG4vLyDqs6DsoJXtlZzri6QuIG9wdXMtNC03IOydgCDsi6TsuKEg7KCE6rmM7KeAIOuvuO2PrO2VqC4g7IOIIOuqqOuNuCDstpTqsIAg7IucIOqzteyLnSDsgqzslpHqs7wg7Iuk7KCcIENMSSDrj5nsnpHsnYQg7ZmV7J247ZWc64ukLlxuY29uc3QgT05FX01JTExJT05fQ09OVEVYVF9NT0RFTFMgPSBuZXcgU2V0KFtcbiAgXCJjbGF1ZGUtZmFibGUtNS0xXCIsXG4gIFwiY2xhdWRlLWZhYmxlLTVcIixcbiAgXCJjbGF1ZGUtb3B1cy01XCIsXG4gIFwiY2xhdWRlLW9wdXMtNS01XCIsXG4gIFwiY2xhdWRlLXNvbm5ldC01LTVcIixcbiAgXCJjbGF1ZGUtc29ubmV0LTVcIixcbiAgXCJjbGF1ZGUtc29ubmV0LTQtNlwiLFxuICBcImNsYXVkZS1vcHVzLTQtNlwiLFxuICBcImNsYXVkZS1vcHVzLTQtOFwiLFxuXSk7XG5cbmNvbnN0IENMSV9PTkVfTUlMTElPTl9TVUZGSVhfTU9ERUxTID0gbmV3IFNldChbXCJjbGF1ZGUtc29ubmV0LTQtNlwiLCBcImNsYXVkZS1vcHVzLTQtNlwiXSk7XG4vLyBGYWJsZSA1LzUuMSwgT3B1cyA1LjUsIFNvbm5ldCA1LjUg64qUIHRoaW5raW5nIGRpc2FibGVkIOulvCDqsbDrtoDtlZzri6QoRmFibGU6IENMSSDsubTtg4jroZzqt7ggYHJlamVjdHNfZGlzYWJsZWRfdGhpbmtpbmdgLFxuLy8gT3B1cyA1LjU6IOqzteyLnSDsgqzslpEgXCJjYW4ndCBiZSB0dXJuZWQgb2ZmXCIsIDIwMjYtMDktMjIg7Lac7IucLiBTb25uZXQgNS41OiBBUEkgYHt0eXBlOiBcImRpc2FibGVkXCJ9YCA0MDAsIENMSSDsubTtg4jroZzqt7ggYHJlamVjdHNfZGlzYWJsZWRfdGhpbmtpbmdgLCAyMDI2LTA5LTI5IOy2nOyLnCkuIE9wdXMgNSDripRcbi8vIGRpc2FibGVkIOulvCBoaWdoIOydtO2VmOyXkOyEnCDsp4Dsm5DtlZjsp4Drp4wsIOqzteyLnSDquLDrs7jqsJLCt+q2jOyepSDrj5nsnpHsnbggYWRhcHRpdmUgdGhpbmtpbmcg7J2EIOycoOyngO2VnOuLpC4gcWdyaWRcbi8vIOq4sOuzuCBlZmZvcnQ9bG93IOqwgCDruYTsmqkv7KeA7JewIOygnOyWtOulvCDrp6HsnLzrqbAsIOydtCDsoJXssYXsnYAgZGlzYWJsZWQreGhpZ2gvbWF4IDQwMCDsmKTrpZjsmYAgZGlzYWJsZWQg7IucXG4vLyB0b29sL1hNTCDstpzroKUg7Jik7Je864+EIO2UvO2VnOuLpC5cbmNvbnN0IEFEQVBUSVZFX1RISU5LSU5HX01PREVMUyA9IG5ldyBTZXQoW1xuICBcImNsYXVkZS1mYWJsZS01LTFcIixcbiAgXCJjbGF1ZGUtZmFibGUtNVwiLFxuICBcImNsYXVkZS1vcHVzLTVcIixcbiAgXCJjbGF1ZGUtb3B1cy01LTVcIixcbiAgXCJjbGF1ZGUtc29ubmV0LTUtNVwiLFxuXSk7XG5cbi8vIEZhYmxlIOqzhOyXtDog6rWs64+FIO2UjOuenOyXkOyEnCB1c2FnZSBjcmVkaXRzIOqwgCDtlYTsmpTtlZwg7LWc7IOB7JyEIO2LsOyWtC4g6rWs64+FIHVzYWdlIEFQSSDsnZhcbi8vIGBzZXZlbl9kYXlfb3ZlcmFnZV9pbmNsdWRlZGAg67KE7YK37J2AIOydtCDqs4Tsl7Tsl5Drp4wg7KCB7Jqp65CY66+A66GcIHF1b3RhIHRocmVzaG9sZCDtjJDsoJXsnbQg7LC47KGw7ZWc64ukLlxuLy8gTXl0aG9zIOuKlCBQcm9qZWN0IEdsYXNzd2luZyDsobDsp4Eg7KCE7Jqp7J206528IOq1rOuPhSDthqDtgbAg6rK966Gc7JeQ7IScIOuPhOuLrO2VoCDsiJgg7JeG7Ja0IO2PrO2VqO2VmOyngCDslYrripTri6QuXG5jb25zdCBGQUJMRV9GQU1JTFlfTU9ERUxTID0gbmV3IFNldChbXCJjbGF1ZGUtZmFibGUtNS0xXCIsIFwiY2xhdWRlLWZhYmxlLTVcIl0pO1xuXG4vLyDrtojrs4Ag6rOE7JW9OiBzdWZmaXgg6rCAIO2VhOyalO2VnCDrqqjrjbjsnYAg67CY65Oc7IucIDFNIOyngOybkCDrqqjrjbjsnZgg67aA67aE7KeR7ZWp7J207Ja07JW8IO2VnOuLpC4g7Jet67Cp7ZalIOu2iOydvOy5mChzdWZmaXhcbi8vIOuMgOyDgeyduOuNsCDsp4Dsm5Ag7KeR7ZWp7JeUIOyXhuydjCnrqbQgbmVlZHNDbGkxbVN1ZmZpeD10cnVlwrdzdXBwb3J0czFNQ29udGV4dD1mYWxzZSDqsIAg64+Z7Iuc7JeQIOuCmOyEnFxuLy8gYC0tbW9kZWwgWzFtXWAg6rO8IERJU0FCTEVfMU0gZW52IOqwgCDrqqjsiJzrkJjqsowg67aZ64qU64ukLiDsg4gg66qo64247J2EIO2VnOyqvSBTZXQg7JeQ66eMIOuEo+uKlCDsi6TsiJjrpbwg66qo65OIXG4vLyDroZzrk5wg7Iuc7KCQ7JeQIOyeoeuKlOuLpC5cbmZvciAoY29uc3QgbW9kZWwgb2YgQ0xJX09ORV9NSUxMSU9OX1NVRkZJWF9NT0RFTFMpIHtcbiAgaWYgKCFPTkVfTUlMTElPTl9DT05URVhUX01PREVMUy5oYXMobW9kZWwpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBbaW52YXJpYW50XSBDTEkgMU0gc3VmZml4IG1vZGVsIG5vdCBpbiBjb250ZXh0IHNldDogJHttb2RlbH1gKTtcbiAgfVxufVxuLy8gRmFibGUg6rOE7Je07J2AIOqzteyLnSDsgqzslpHsg4EgMU0g6riw67O4IOy7qO2FjeyKpO2KuCArIGFkYXB0aXZlIHRoaW5raW5nIO2VhOyImOuLpC4g7IOIIEZhYmxlIOuyhOyghOydhCDqs4Tsl7QgU2V0XG4vLyDsl5Drp4wg64Sj6rOgIOuCmOuouOyngOulvCDruaDrnKjrpqzripQg7Iuk7IiY66W8IOqwmeydgCDrsKnsi53snLzroZwg66qo65OIIOuhnOuTnCDsi5zsoJDsl5Ag7J6h64qU64ukLlxuZm9yIChjb25zdCBtb2RlbCBvZiBGQUJMRV9GQU1JTFlfTU9ERUxTKSB7XG4gIGlmICghT05FX01JTExJT05fQ09OVEVYVF9NT0RFTFMuaGFzKG1vZGVsKSB8fCAhQURBUFRJVkVfVEhJTktJTkdfTU9ERUxTLmhhcyhtb2RlbCkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYFtpbnZhcmlhbnRdIEZhYmxlIGZhbWlseSBtb2RlbCBtaXNzaW5nIGZyb20gMU0vYWRhcHRpdmUgc2V0OiAke21vZGVsfWApO1xuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzdXBwb3J0czFNQ29udGV4dChtb2RlbD86IHN0cmluZyk6IGJvb2xlYW4ge1xuICByZXR1cm4gT05FX01JTExJT05fQ09OVEVYVF9NT0RFTFMuaGFzKGNhbm9uaWNhbEFudGhyb3BpY01vZGVsKG1vZGVsKSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBuZWVkc0NsaTFtU3VmZml4KG1vZGVsPzogc3RyaW5nKTogYm9vbGVhbiB7XG4gIHJldHVybiBDTElfT05FX01JTExJT05fU1VGRklYX01PREVMUy5oYXMoY2Fub25pY2FsQW50aHJvcGljTW9kZWwobW9kZWwpKTtcbn1cblxuLy8gcWdyaWQg6rCAIGFkYXB0aXZlIHRoaW5raW5nIOydhCDrs7TsobTtlZjripQg66qo64247J247KeAIO2MkOuzhO2VnOuLpC4g64KY66i47KeAIOuqqOuNuOydgCDquLDsobRcbi8vIOyggOu5hOyaqS/ruYTstpTroaAg6rK966Gc66W8IOycoOyngO2VnOuLpC5cbmV4cG9ydCBmdW5jdGlvbiB1c2VzQWRhcHRpdmVUaGlua2luZyhtb2RlbD86IHN0cmluZyk6IGJvb2xlYW4ge1xuICByZXR1cm4gQURBUFRJVkVfVEhJTktJTkdfTU9ERUxTLmhhcyhjYW5vbmljYWxBbnRocm9waWNNb2RlbChtb2RlbCkpO1xufVxuXG4vLyDqtazrj4UgdXNhZ2Ug7J2YIEZhYmxlIOyghOyaqSA37J28IOuyhO2Ct+ydhCBxdW90YSDtjJDsoJXsl5Ag7Y+s7ZWo7ZWg7KeAIOqysOygle2VnOuLpC5cbmV4cG9ydCBmdW5jdGlvbiBpc0ZhYmxlRmFtaWx5TW9kZWwobW9kZWw/OiBzdHJpbmcpOiBib29sZWFuIHtcbiAgcmV0dXJuIEZBQkxFX0ZBTUlMWV9NT0RFTFMuaGFzKGNhbm9uaWNhbEFudGhyb3BpY01vZGVsKG1vZGVsKSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhc3NlcnRTdXBwb3J0ZWRPbmVNaWxsaW9uU3VmZml4KG1vZGVsPzogc3RyaW5nKTogdm9pZCB7XG4gIGlmICghaGFzT25lTWlsbGlvblN1ZmZpeChtb2RlbCkpIHJldHVybjtcbiAgY29uc3QgY2Fub25pY2FsID0gY2Fub25pY2FsQW50aHJvcGljTW9kZWwobW9kZWwpO1xuICBpZiAoIXN1cHBvcnRzMU1Db250ZXh0KGNhbm9uaWNhbCkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYFVuc3VwcG9ydGVkIEFudGhyb3BpYyAxTSBtb2RlbCBzdWZmaXg6ICR7bW9kZWx9YCk7XG4gIH1cbn1cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7O0FBWUEsTUFBYSwwQkFBMEI7QUFFdkMsTUFBYSwyQkFBMkI7QUFFeEMsTUFBYSx1QkFBdUI7QUFFcEMsTUFBYSw0QkFBNEI7QUFFekMsTUFBYSw2QkFBNkI7Q0FBQztDQUFXO0NBQW9CO0FBQWU7QUFDekYsTUFBTSx3QkFBd0I7QUFLOUIsU0FBZ0IsbUJBQW1CLFNBQXlCO0NBQzFELE9BQU8sR0FBRywwQkFBMEIsR0FBRztBQUN6QztBQU1BLFNBQWdCLHdCQUF3QixPQUF3QjtDQUM5RCxNQUFNLE1BQU0sU0FBQTtDQUVaLFFBRHdCLElBQUksU0FBUyxHQUFHLElBQUksSUFBSSxNQUFNLEdBQUcsQ0FBQyxDQUFDLElBQUksSUFBSyxJQUM3RCxDQUFnQixRQUFRLHVCQUF1QixFQUFFO0FBQzFEO0FBRUEsU0FBZ0Isb0JBQW9CLE9BQXlCO0NBQzNELE9BQU8sVUFBVSxVQUFhLHNCQUFzQixLQUFLLEtBQUs7QUFDaEU7QUFJQSxNQUFNLDZDQUE2QixJQUFJLElBQUk7Q0FDekM7Q0FDQTtDQUNBO0NBQ0E7Q0FDQTtDQUNBO0NBQ0E7Q0FDQTtDQUNBO0FBQ0YsQ0FBQztBQUVELE1BQU0sZ0RBQWdDLElBQUksSUFBSSxDQUFDLHFCQUFxQixpQkFBaUIsQ0FBQztBQU10RixNQUFNLDJDQUEyQixJQUFJLElBQUk7Q0FDdkM7Q0FDQTtDQUNBO0NBQ0E7Q0FDQTtBQUNGLENBQUM7QUFLRCxNQUFNLHNDQUFzQixJQUFJLElBQUksQ0FBQyxvQkFBb0IsZ0JBQWdCLENBQUM7QUFNMUUsS0FBSyxNQUFNLFNBQVMsK0JBQ2xCLElBQUksQ0FBQywyQkFBMkIsSUFBSSxLQUFLLEdBQ3ZDLE1BQU0sSUFBSSxNQUFNLHVEQUF1RCxPQUFPO0FBS2xGLEtBQUssTUFBTSxTQUFTLHFCQUNsQixJQUFJLENBQUMsMkJBQTJCLElBQUksS0FBSyxLQUFLLENBQUMseUJBQXlCLElBQUksS0FBSyxHQUMvRSxNQUFNLElBQUksTUFBTSxnRUFBZ0UsT0FBTztBQUkzRixTQUFnQixrQkFBa0IsT0FBeUI7Q0FDekQsT0FBTywyQkFBMkIsSUFBSSx3QkFBd0IsS0FBSyxDQUFDO0FBQ3RFO0FBRUEsU0FBZ0IsaUJBQWlCLE9BQXlCO0NBQ3hELE9BQU8sOEJBQThCLElBQUksd0JBQXdCLEtBQUssQ0FBQztBQUN6RTtBQUlBLFNBQWdCLHFCQUFxQixPQUF5QjtDQUM1RCxPQUFPLHlCQUF5QixJQUFJLHdCQUF3QixLQUFLLENBQUM7QUFDcEU7QUFHQSxTQUFnQixtQkFBbUIsT0FBeUI7Q0FDMUQsT0FBTyxvQkFBb0IsSUFBSSx3QkFBd0IsS0FBSyxDQUFDO0FBQy9EO0FBRUEsU0FBZ0IsZ0NBQWdDLE9BQXNCO0NBQ3BFLElBQUksQ0FBQyxvQkFBb0IsS0FBSyxHQUFHO0NBRWpDLElBQUksQ0FBQyxrQkFEYSx3QkFBd0IsS0FDbkIsQ0FBUyxHQUM5QixNQUFNLElBQUksTUFBTSwwQ0FBMEMsT0FBTztBQUVyRSJ9
73
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYW50aHJvcGljLWNvbnN0YW50cy5qcyIsIm5hbWVzIjpbXSwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvdXRpbHMvcHJvdmlkZXJzL2FudGhyb3BpYy9hbnRocm9waWMtY29uc3RhbnRzLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQW50aHJvcGljKENsYXVkZSkgcHJvdmlkZXIg7IOB7IiYLlxuICpcbiAqIENsYXVkZSBDb2RlIENMSSDtlIzrnpjqt7gvZW52IOqzhOyVveydhCBBbnRocm9waWMgZGlzcGF0Y2hlciDsmqnsnLzroZwg6rOg7KCV7ZWc64ukOlxuICogIC0gYC0tbm8tc2Vzc2lvbi1wZXJzaXN0ZW5jZWAg7KCc6rGwICjrqYDti7DthLQg7ZWE7IiYKS5cbiAqICAtIGAtLWlucHV0LWZvcm1hdCBzdHJlYW0tanNvbmAg7LaU6rCAIChzdGRpbiDsnLzroZwg7J6F66ClIOyWtOuMke2EsCBKU09OTCDtnZjrprwpLlxuICogIC0gQW50aHJvcGljIOqyveuhnOuKlCDrp6Qg7Zi47LacIGAtLXNlc3Npb24taWRgIOuhnCBmcmVzaCBzZXNzaW9uIOydhCDrsJzquIntlZzri6QuXG4gKi9cblxuLy8gQ0MgLS1tb2RlbCDtlIzrnpjqt7jqsIAg67Cb64qUIG9mZmljaWFsIG1vZGVsIGlkIChhbGlhcyBcInNvbm5ldFwiIOqwgCDslYTri4jrnbwg7KCV7ZmV7ZWcIOyLneuzhOyekOuhnCDqs6DsoJUpLlxuLy8gY2xhdWRlLWFwaSDsiqTtgqwg7ZmV7J24OiBTb25uZXQgNC42IG9mZmljaWFsIGlkID0gXCJjbGF1ZGUtc29ubmV0LTQtNlwiICjrgqDsp5wgc3VmZml4IOyXhuydjCkuXG4vLyBtb2RlbC1jb3N0IO2FjOydtOu4lOyXkOuPhCBcImNsYXVkZS1zb25uZXQtNC02XCIg7YKkIOyhtOyerFxuZXhwb3J0IGNvbnN0IEFOVEhST1BJQ19ERUZBVUxUX01PREVMID0gXCJjbGF1ZGUtc29ubmV0LTQtNlwiO1xuLy8gT3BlbkFJIHByb3ZpZGVyIOq4sOuzuOqwkihvcGVuYWktZGlzcGF0Y2hlciBERUZBVUxUX0VGRk9SVCnqs7wg66ee7LaY64ukLiDtgbTrnbzqsIAgZWZmb3J0IOuvuOyngOyglSDsi5wg7JWI7KCE66edLlxuZXhwb3J0IGNvbnN0IEFOVEhST1BJQ19ERUZBVUxUX0VGRk9SVCA9IFwibG93XCI7XG4vLyBwcm9qZWN0IHNjb3BlIGN3ZCAoc2V0dGluZ3MuanNvbiDqsqnrpqwpLiDthqDtgbDrs4Qg6rKp66as64qUIENMQVVERV9DT05GSUdfRElSIOuhnCDtlZzri6QuXG5leHBvcnQgY29uc3QgQU5USFJPUElDX0NMQVVERV9DV0QgPSBcIi90bXAvcWdyaWQtYW50aHJvcGljXCI7XG4vLyBwZXItdG9rZW4gQ0xBVURFX0NPTkZJR19ESVIg7J2YIOuyoOydtOyKpC4g7Iuk7KCcIOqyveuhnOuKlCBgJHtCQVNFfS8ke3Rva2VuSWR9YCAoUjEwIOqyqeumrCkuXG5leHBvcnQgY29uc3QgQU5USFJPUElDX0NPTkZJR19ESVJfQkFTRSA9IFwiL3RtcC9xZ3JpZC1hbnRocm9waWMtY29uZmlnXCI7XG4vLyBDQyDqsIAg7J6Q64+ZIO2ZnOyEse2ZlO2VmOuKlCBkZWZlcnJlZCDrj4Tqtawg4oCUIO2GoO2BsCDstZzsoIHtmZQg7JyE7ZW0IGRpc3BhdGNoZXIg6rK966Gc7JeQ7IScIOywqOuLqC5cbmV4cG9ydCBjb25zdCBBTlRIUk9QSUNfRElTQUxMT1dFRF9UT09MUyA9IFtcIk1vbml0b3JcIiwgXCJQdXNoTm90aWZpY2F0aW9uXCIsIFwiUmVtb3RlVHJpZ2dlclwiXSBhcyBjb25zdDtcbmNvbnN0IE9ORV9NSUxMSU9OX1NVRkZJWF9SRSA9IC9cXFsxbVxcXSQvaTtcblxuLy8g7Yag7YGw67OEIENMQVVERV9DT05GSUdfRElSIOqyveuhnCDqt5zsuZkoUjEwIOqyqeumrCDqs4Tslb0pLiB0b2tlbklkIOuzhOuhnCDrtoTrpqzrkJjslrQsIOqwmeydgCBjbGF1ZGUgc2Vzc2lvbi1pZFxuLy8g652864+EIOuLpOuluCDthqDtgbDsnbTrqbQg64uk66W4IGNvbmZpZyBkaXIg4oaSIHRyYW5zY3JpcHQg6rCAIOyEnuydtOyngCDslYrripTri6QuIOu2gOyImO2aqOqzvCDsl4bripQg7Iic7IiYIO2VqOyImOudvFxuLy8g6rKp66asIOqzhOyVveydhCDri6jsnIQg7YWM7Iqk7Yq466GcIOqzoOygle2VoCDsiJgg7J6I64ukKFU2IFIxMCDqtazsobAg6rKA7KadKS4g7Iuk7KCcIGRpciDsg53shLHsnYAgZW5zdXJlQ29uZmlnRGlyIOqwgCDtlZzri6QuXG5leHBvcnQgZnVuY3Rpb24gYW50aHJvcGljQ29uZmlnRGlyKHRva2VuSWQ6IG51bWJlcik6IHN0cmluZyB7XG4gIHJldHVybiBgJHtBTlRIUk9QSUNfQ09ORklHX0RJUl9CQVNFfS8ke3Rva2VuSWR9YDtcbn1cblxuLy8gbW9kZWwgaWQg66W8IGNhbm9uaWNhbChwcm92aWRlciBwcmVmaXgg7JeG64qUIENMSS9jb3N0IO2CpCkg66GcIOygleq3nO2ZlFxuLy8gYWktc2RrIOuKlCAnYW50aHJvcGljL2NsYXVkZS0qJyDtmJXtg5zroZwg67O064K064qU642wLCBwcmVmaXgg6rCAIGNhbGN1bGF0ZUNvc3RVc2Qg7JeQIOyDiOuptCBjb3N0IOqwgFxuLy8gZGVmYXVsdCDri6jqsIDroZwg7Jik6rOE7IKw65Cc64ukLiBgWzFtXWAgc3VmZml4IOuPhCBDTEkgZW1pdCDsoITsmqnsnbTrnbxcbi8vIGJhc2UgY2Fub25pY2FsIOyXkOyEnOuKlCDsoJzqsbDtlZzri6QuIOuvuOyngOygleydtOuptCBkZWZhdWx0LlxuZXhwb3J0IGZ1bmN0aW9uIGNhbm9uaWNhbEFudGhyb3BpY01vZGVsKG1vZGVsPzogc3RyaW5nKTogc3RyaW5nIHtcbiAgY29uc3QgcmF3ID0gbW9kZWwgfHwgQU5USFJPUElDX0RFRkFVTFRfTU9ERUw7XG4gIGNvbnN0IHdpdGhvdXRQcm92aWRlciA9IHJhdy5pbmNsdWRlcyhcIi9cIikgPyByYXcuc3BsaXQoXCIvXCIpLnBvcCgpISA6IHJhdztcbiAgcmV0dXJuIHdpdGhvdXRQcm92aWRlci5yZXBsYWNlKE9ORV9NSUxMSU9OX1NVRkZJWF9SRSwgXCJcIik7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBoYXNPbmVNaWxsaW9uU3VmZml4KG1vZGVsPzogc3RyaW5nKTogYm9vbGVhbiB7XG4gIHJldHVybiBtb2RlbCAhPT0gdW5kZWZpbmVkICYmIE9ORV9NSUxMSU9OX1NVRkZJWF9SRS50ZXN0KG1vZGVsKTtcbn1cblxuLy8gMU0g7KeA7JuQIOyXrOu2gOuKlCBDbGF1ZGUgQ29kZSDrgrTrtoDsnZgg6rSR67KU7JyE7ZWcIHByZWZpeCDtjJDsoJXsnbQg7JWE64uI6528IHFncmlk7JeQ7IScIO2ZleyduO2VnCBleGFjdCBzZXQg7Jy866GcXG4vLyDqs6DsoJXtlZzri6QuIG9wdXMtNC03IOydgCDsi6TsuKEg7KCE6rmM7KeAIOuvuO2PrO2VqC4g7IOIIOuqqOuNuCDstpTqsIAg7IucIOqzteyLnSDsgqzslpHqs7wg7Iuk7KCcIENMSSDrj5nsnpHsnYQg7ZmV7J247ZWc64ukLlxuY29uc3QgT05FX01JTExJT05fQ09OVEVYVF9NT0RFTFMgPSBuZXcgU2V0KFtcbiAgXCJjbGF1ZGUtZmFibGUtNS0xXCIsXG4gIFwiY2xhdWRlLWZhYmxlLTVcIixcbiAgXCJjbGF1ZGUtb3B1cy01XCIsXG4gIFwiY2xhdWRlLW9wdXMtNS01XCIsXG4gIFwiY2xhdWRlLXNvbm5ldC01LTVcIixcbiAgXCJjbGF1ZGUtc29ubmV0LTVcIixcbiAgXCJjbGF1ZGUtaGFpa3UtNS01XCIsXG4gIFwiY2xhdWRlLXNvbm5ldC00LTZcIixcbiAgXCJjbGF1ZGUtb3B1cy00LTZcIixcbiAgXCJjbGF1ZGUtb3B1cy00LThcIixcbl0pO1xuXG5jb25zdCBDTElfT05FX01JTExJT05fU1VGRklYX01PREVMUyA9IG5ldyBTZXQoW1wiY2xhdWRlLXNvbm5ldC00LTZcIiwgXCJjbGF1ZGUtb3B1cy00LTZcIl0pO1xuLy8gRmFibGUgNS81LjEsIE9wdXMgNS41LCBTb25uZXQgNS41LCBIYWlrdSA1LjUg64qUIHRoaW5raW5nIGRpc2FibGVkIOulvCDqsbDrtoDtlZzri6QoRmFibGU6IENMSSDsubTtg4jroZzqt7ggYHJlamVjdHNfZGlzYWJsZWRfdGhpbmtpbmdgLFxuLy8gT3B1cyA1LjU6IOqzteyLnSDsgqzslpEgXCJjYW4ndCBiZSB0dXJuZWQgb2ZmXCIsIDIwMjYtMDktMjIg7Lac7IucLiBTb25uZXQgNS41OiBBUEkgYHt0eXBlOiBcImRpc2FibGVkXCJ9YCA0MDAsIENMSSDsubTtg4jroZzqt7ggYHJlamVjdHNfZGlzYWJsZWRfdGhpbmtpbmdgLCAyMDI2LTA5LTI4IOy2nOyLnC5cbi8vIEhhaWt1IDUuNTogQVBJIOuKlCBoaWdoIOydtO2VmOyXkOyEnOunjCBkaXNhYmxlZCDtl4jsmqnCt3hoaWdoL21heCA0MDAsIENsYXVkZSBDb2RlIDIuMS4yOTMg7Lm07YOI66Gc6re464qUIGByZWplY3RzX2Rpc2FibGVkX3RoaW5raW5nYCwgMjAyNi0xMC0wNyDstpzsi5wpLiBPcHVzIDUg64qUXG4vLyBkaXNhYmxlZCDrpbwgaGlnaCDsnbTtlZjsl5DshJwg7KeA7JuQ7ZWY7KeA66eMLCDqs7Xsi50g6riw67O46rCSwrfqtozsnqUg64+Z7J6R7J24IGFkYXB0aXZlIHRoaW5raW5nIOydhCDsnKDsp4DtlZzri6QuIHFncmlkXG4vLyDquLDrs7ggZWZmb3J0PWxvdyDqsIAg67mE7JqpL+yngOyXsCDsoJzslrTrpbwg66eh7Jy866mwLCDsnbQg7KCV7LGF7J2AIGRpc2FibGVkK3hoaWdoL21heCA0MDAg7Jik66WY7JmAIGRpc2FibGVkIOyLnFxuLy8gdG9vbC9YTUwg7Lac66ClIOyYpOyXvOuPhCDtlLztlZzri6QuXG5jb25zdCBBREFQVElWRV9USElOS0lOR19NT0RFTFMgPSBuZXcgU2V0KFtcbiAgXCJjbGF1ZGUtZmFibGUtNS0xXCIsXG4gIFwiY2xhdWRlLWZhYmxlLTVcIixcbiAgXCJjbGF1ZGUtb3B1cy01XCIsXG4gIFwiY2xhdWRlLW9wdXMtNS01XCIsXG4gIFwiY2xhdWRlLXNvbm5ldC01LTVcIixcbiAgXCJjbGF1ZGUtaGFpa3UtNS01XCIsXG5dKTtcblxuLy8gRmFibGUg6rOE7Je0OiDqtazrj4Ug7ZSM656c7JeQ7IScIHVzYWdlIGNyZWRpdHMg6rCAIO2VhOyalO2VnCDstZzsg4HsnIQg7Yuw7Ja0LiDqtazrj4UgdXNhZ2UgQVBJIOydmFxuLy8gYHNldmVuX2RheV9vdmVyYWdlX2luY2x1ZGVkYCDrsoTtgrfsnYAg7J20IOqzhOyXtOyXkOunjCDsoIHsmqnrkJjrr4DroZwgcXVvdGEgdGhyZXNob2xkIO2MkOygleydtCDssLjsobDtlZzri6QuXG4vLyBNeXRob3Mg64qUIFByb2plY3QgR2xhc3N3aW5nIOyhsOyngSDsoITsmqnsnbTrnbwg6rWs64+FIO2GoO2BsCDqsr3roZzsl5DshJwg64+E64us7ZWgIOyImCDsl4bslrQg7Y+s7ZWo7ZWY7KeAIOyViuuKlOuLpC5cbmNvbnN0IEZBQkxFX0ZBTUlMWV9NT0RFTFMgPSBuZXcgU2V0KFtcImNsYXVkZS1mYWJsZS01LTFcIiwgXCJjbGF1ZGUtZmFibGUtNVwiXSk7XG5cbi8vIOu2iOuzgCDqs4Tslb06IHN1ZmZpeCDqsIAg7ZWE7JqU7ZWcIOuqqOuNuOydgCDrsJjrk5zsi5wgMU0g7KeA7JuQIOuqqOuNuOydmCDrtoDrtoTsp5HtlansnbTslrTslbwg7ZWc64ukLiDsl63rsKntlqUg67aI7J287LmYKHN1ZmZpeFxuLy8g64yA7IOB7J24642wIOyngOybkCDsp5Htlansl5Qg7JeG7J2MKeuptCBuZWVkc0NsaTFtU3VmZml4PXRydWXCt3N1cHBvcnRzMU1Db250ZXh0PWZhbHNlIOqwgCDrj5nsi5zsl5Ag64KY7IScXG4vLyBgLS1tb2RlbCBbMW1dYCDqs7wgRElTQUJMRV8xTSBlbnYg6rCAIOuqqOyInOuQmOqyjCDrtpnripTri6QuIOyDiCDrqqjrjbjsnYQg7ZWc7Kq9IFNldCDsl5Drp4wg64Sj64qUIOyLpOyImOulvCDrqqjrk4hcbi8vIOuhnOuTnCDsi5zsoJDsl5Ag7J6h64qU64ukLlxuZm9yIChjb25zdCBtb2RlbCBvZiBDTElfT05FX01JTExJT05fU1VGRklYX01PREVMUykge1xuICBpZiAoIU9ORV9NSUxMSU9OX0NPTlRFWFRfTU9ERUxTLmhhcyhtb2RlbCkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYFtpbnZhcmlhbnRdIENMSSAxTSBzdWZmaXggbW9kZWwgbm90IGluIGNvbnRleHQgc2V0OiAke21vZGVsfWApO1xuICB9XG59XG4vLyBGYWJsZSDqs4Tsl7TsnYAg6rO17IudIOyCrOyWkeyDgSAxTSDquLDrs7gg7Luo7YWN7Iqk7Yq4ICsgYWRhcHRpdmUgdGhpbmtpbmcg7ZWE7IiY64ukLiDsg4ggRmFibGUg67KE7KCE7J2EIOqzhOyXtCBTZXRcbi8vIOyXkOunjCDrhKPqs6Ag64KY66i47KeA66W8IOu5oOucqOumrOuKlCDsi6TsiJjrpbwg6rCZ7J2AIOuwqeyLneycvOuhnCDrqqjrk4gg66Gc65OcIOyLnOygkOyXkCDsnqHripTri6QuXG5mb3IgKGNvbnN0IG1vZGVsIG9mIEZBQkxFX0ZBTUlMWV9NT0RFTFMpIHtcbiAgaWYgKCFPTkVfTUlMTElPTl9DT05URVhUX01PREVMUy5oYXMobW9kZWwpIHx8ICFBREFQVElWRV9USElOS0lOR19NT0RFTFMuaGFzKG1vZGVsKSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgW2ludmFyaWFudF0gRmFibGUgZmFtaWx5IG1vZGVsIG1pc3NpbmcgZnJvbSAxTS9hZGFwdGl2ZSBzZXQ6ICR7bW9kZWx9YCk7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHN1cHBvcnRzMU1Db250ZXh0KG1vZGVsPzogc3RyaW5nKTogYm9vbGVhbiB7XG4gIHJldHVybiBPTkVfTUlMTElPTl9DT05URVhUX01PREVMUy5oYXMoY2Fub25pY2FsQW50aHJvcGljTW9kZWwobW9kZWwpKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIG5lZWRzQ2xpMW1TdWZmaXgobW9kZWw/OiBzdHJpbmcpOiBib29sZWFuIHtcbiAgcmV0dXJuIENMSV9PTkVfTUlMTElPTl9TVUZGSVhfTU9ERUxTLmhhcyhjYW5vbmljYWxBbnRocm9waWNNb2RlbChtb2RlbCkpO1xufVxuXG4vLyBxZ3JpZCDqsIAgYWRhcHRpdmUgdGhpbmtpbmcg7J2EIOuztOyhtO2VmOuKlCDrqqjrjbjsnbjsp4Ag7YyQ67OE7ZWc64ukLiDrgpjrqLjsp4Ag66qo64247J2AIOq4sOyhtFxuLy8g7KCA67mE7JqpL+u5hOy2lOuhoCDqsr3roZzrpbwg7Jyg7KeA7ZWc64ukLlxuZXhwb3J0IGZ1bmN0aW9uIHVzZXNBZGFwdGl2ZVRoaW5raW5nKG1vZGVsPzogc3RyaW5nKTogYm9vbGVhbiB7XG4gIHJldHVybiBBREFQVElWRV9USElOS0lOR19NT0RFTFMuaGFzKGNhbm9uaWNhbEFudGhyb3BpY01vZGVsKG1vZGVsKSk7XG59XG5cbi8vIOq1rOuPhSB1c2FnZSDsnZggRmFibGUg7KCE7JqpIDfsnbwg67KE7YK37J2EIHF1b3RhIO2MkOygleyXkCDtj6ztlajtlaDsp4Ag6rKw7KCV7ZWc64ukLlxuZXhwb3J0IGZ1bmN0aW9uIGlzRmFibGVGYW1pbHlNb2RlbChtb2RlbD86IHN0cmluZyk6IGJvb2xlYW4ge1xuICByZXR1cm4gRkFCTEVfRkFNSUxZX01PREVMUy5oYXMoY2Fub25pY2FsQW50aHJvcGljTW9kZWwobW9kZWwpKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGFzc2VydFN1cHBvcnRlZE9uZU1pbGxpb25TdWZmaXgobW9kZWw/OiBzdHJpbmcpOiB2b2lkIHtcbiAgaWYgKCFoYXNPbmVNaWxsaW9uU3VmZml4KG1vZGVsKSkgcmV0dXJuO1xuICBjb25zdCBjYW5vbmljYWwgPSBjYW5vbmljYWxBbnRocm9waWNNb2RlbChtb2RlbCk7XG4gIGlmICghc3VwcG9ydHMxTUNvbnRleHQoY2Fub25pY2FsKSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgVW5zdXBwb3J0ZWQgQW50aHJvcGljIDFNIG1vZGVsIHN1ZmZpeDogJHttb2RlbH1gKTtcbiAgfVxufVxuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7QUFZQSxNQUFhLDBCQUEwQjtBQUV2QyxNQUFhLDJCQUEyQjtBQUV4QyxNQUFhLHVCQUF1QjtBQUVwQyxNQUFhLDRCQUE0QjtBQUV6QyxNQUFhLDZCQUE2QjtDQUFDO0NBQVc7Q0FBb0I7QUFBZTtBQUN6RixNQUFNLHdCQUF3QjtBQUs5QixTQUFnQixtQkFBbUIsU0FBeUI7Q0FDMUQsT0FBTyxHQUFHLDBCQUEwQixHQUFHO0FBQ3pDO0FBTUEsU0FBZ0Isd0JBQXdCLE9BQXdCO0NBQzlELE1BQU0sTUFBTSxTQUFBO0NBRVosUUFEd0IsSUFBSSxTQUFTLEdBQUcsSUFBSSxJQUFJLE1BQU0sR0FBRyxDQUFDLENBQUMsSUFBSSxJQUFLLElBQzdELENBQWdCLFFBQVEsdUJBQXVCLEVBQUU7QUFDMUQ7QUFFQSxTQUFnQixvQkFBb0IsT0FBeUI7Q0FDM0QsT0FBTyxVQUFVLFVBQWEsc0JBQXNCLEtBQUssS0FBSztBQUNoRTtBQUlBLE1BQU0sNkNBQTZCLElBQUksSUFBSTtDQUN6QztDQUNBO0NBQ0E7Q0FDQTtDQUNBO0NBQ0E7Q0FDQTtDQUNBO0NBQ0E7Q0FDQTtBQUNGLENBQUM7QUFFRCxNQUFNLGdEQUFnQyxJQUFJLElBQUksQ0FBQyxxQkFBcUIsaUJBQWlCLENBQUM7QUFPdEYsTUFBTSwyQ0FBMkIsSUFBSSxJQUFJO0NBQ3ZDO0NBQ0E7Q0FDQTtDQUNBO0NBQ0E7Q0FDQTtBQUNGLENBQUM7QUFLRCxNQUFNLHNDQUFzQixJQUFJLElBQUksQ0FBQyxvQkFBb0IsZ0JBQWdCLENBQUM7QUFNMUUsS0FBSyxNQUFNLFNBQVMsK0JBQ2xCLElBQUksQ0FBQywyQkFBMkIsSUFBSSxLQUFLLEdBQ3ZDLE1BQU0sSUFBSSxNQUFNLHVEQUF1RCxPQUFPO0FBS2xGLEtBQUssTUFBTSxTQUFTLHFCQUNsQixJQUFJLENBQUMsMkJBQTJCLElBQUksS0FBSyxLQUFLLENBQUMseUJBQXlCLElBQUksS0FBSyxHQUMvRSxNQUFNLElBQUksTUFBTSxnRUFBZ0UsT0FBTztBQUkzRixTQUFnQixrQkFBa0IsT0FBeUI7Q0FDekQsT0FBTywyQkFBMkIsSUFBSSx3QkFBd0IsS0FBSyxDQUFDO0FBQ3RFO0FBRUEsU0FBZ0IsaUJBQWlCLE9BQXlCO0NBQ3hELE9BQU8sOEJBQThCLElBQUksd0JBQXdCLEtBQUssQ0FBQztBQUN6RTtBQUlBLFNBQWdCLHFCQUFxQixPQUF5QjtDQUM1RCxPQUFPLHlCQUF5QixJQUFJLHdCQUF3QixLQUFLLENBQUM7QUFDcEU7QUFHQSxTQUFnQixtQkFBbUIsT0FBeUI7Q0FDMUQsT0FBTyxvQkFBb0IsSUFBSSx3QkFBd0IsS0FBSyxDQUFDO0FBQy9EO0FBRUEsU0FBZ0IsZ0NBQWdDLE9BQXNCO0NBQ3BFLElBQUksQ0FBQyxvQkFBb0IsS0FBSyxHQUFHO0NBRWpDLElBQUksQ0FBQyxrQkFEYSx3QkFBd0IsS0FDbkIsQ0FBUyxHQUM5QixNQUFNLElBQUksTUFBTSwwQ0FBMEMsT0FBTztBQUVyRSJ9
@@ -97,7 +97,8 @@ function anthropicCosts(inputTokens, outputTokens, overrides = {}) {
97
97
  cachedInputTokens: overrides.cachedInputTokens ?? inputTokens / 10,
98
98
  cacheCreationInputTokens: inputTokens * 2,
99
99
  cacheCreationInputTokens5m: inputTokens * 1.25,
100
- cacheCreationInputTokens1h: inputTokens * 2
100
+ cacheCreationInputTokens1h: inputTokens * 2,
101
+ ...overrides.longContext ? { longContext: overrides.longContext } : {}
101
102
  };
102
103
  }
103
104
  const ANTHROPIC_COSTS = {
@@ -121,7 +122,13 @@ const ANTHROPIC_COSTS = {
121
122
  "claude-opus-5": anthropicCosts(5, 25),
122
123
  "claude-opus-5-5": anthropicCosts(4, 20, { cachedInputTokens: .2 }),
123
124
  "claude-sonnet-5": anthropicCosts(2, 10),
124
- "claude-sonnet-5-5": anthropicCosts(2, 10)
125
+ "claude-sonnet-5-5": anthropicCosts(2, 10, { cachedInputTokens: .1 }),
126
+ "claude-haiku-5-5": anthropicCosts(.1, .5, { longContext: {
127
+ threshold: 1e5,
128
+ inputMultiplier: 5,
129
+ cachedInputMultiplier: 5,
130
+ outputMultiplier: 5
131
+ } })
125
132
  };
126
133
  const DEFAULT_COSTS = {
127
134
  inputTokens: 3,
@@ -159,4 +166,4 @@ function calculateCostUsd(model, usage) {
159
166
  //#endregion
160
167
  export { calculateCostUsd, getModelCosts, openaiModelMaxEffort };
161
168
 
162
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9kZWwtY29zdC5qcyIsIm5hbWVzIjpbXSwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvdXRpbHMvcHJvdmlkZXJzL2NvbW1vbi9tb2RlbC1jb3N0LnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICog66qo642467OEIO2GoO2BsCDqsIDqsqkg7YWM7J2067iUICsgY29zdCDqs4TsgrAuXG4gKlxuICogY2xhdWRlIGNvZGUg7JmAIOuPmeydvCDtjKjthLQ6IO2BtOudvOydtOyWuO2KuOyXkOyEnCDqsIDqsqkg7YWM7J2067iU66GcIOyngeygkSDqs4TsgrAuXG4gKiDqsIDqsqkg64uo7JyEOiBVU0QgcGVyIDFNIHRva2Vucy5cbiAqXG4gKiBPcGVuQUkg66qo6424IOuqqeuhneydgCBPcGVuQUkg66qo6424IOusuOyEnOyZgCDtmITsnqwg7KeA7JuQIOuqqeuhneydhCDquLDspIDsnLzroZwg6rSA66as7ZWc64ukLlxuICpcbiAqIEBzZWUgaHR0cHM6Ly9wbGF0Zm9ybS5vcGVuYWkuY29tL2RvY3MvcHJpY2luZ1xuICogQHNlZSBodHRwczovL3BsYXRmb3JtLmNsYXVkZS5jb20vZG9jcy9lbi9hYm91dC1jbGF1ZGUvcHJpY2luZ1xuICovXG5cbmltcG9ydCB7IHR5cGUgT3BlbkFJRWZmb3J0IH0gZnJvbSBcIi4vZWZmb3J0XCI7XG5cbmV4cG9ydCBpbnRlcmZhY2UgTW9kZWxDb3N0cyB7XG4gIGlucHV0VG9rZW5zOiBudW1iZXI7XG4gIG91dHB1dFRva2VuczogbnVtYmVyO1xuICBjYWNoZWRJbnB1dFRva2VuczogbnVtYmVyO1xuICAvKiogVFRMIGJyZWFrZG93biDsnbQg7JeG64qUIHVzYWdlIOyXkCDsoIHsmqntlaAgY2FjaGUgd3JpdGUgZmFsbGJhY2sg64uo6rCALiAqL1xuICBjYWNoZUNyZWF0aW9uSW5wdXRUb2tlbnM/OiBudW1iZXI7XG4gIGNhY2hlQ3JlYXRpb25JbnB1dFRva2VuczVtPzogbnVtYmVyO1xuICBjYWNoZUNyZWF0aW9uSW5wdXRUb2tlbnMxaD86IG51bWJlcjtcbiAgLyoqXG4gICAqIGxvbmctY29udGV4dCDtlaDspp0uIOyghOyytCDsnoXroKUg7Yag7YGwKGlucHV0X3Rva2VucywgY2FjaGVfcmVhZCDtj6ztlagp7J20IHRocmVzaG9sZCDstIjqs7wg7IucXG4gICAqIOy0iOqzvOu2hOunjOydtCDslYTri4jrnbwg7JqU7LKtIOyghOyytChmdWxsIHNlc3Npb24p7JeQIOuwsOycqCDsoIHsmqkuXG4gICAqL1xuICBsb25nQ29udGV4dD86IHtcbiAgICB0aHJlc2hvbGQ6IG51bWJlcjtcbiAgICBpbnB1dE11bHRpcGxpZXI6IG51bWJlcjtcbiAgICBjYWNoZWRJbnB1dE11bHRpcGxpZXI6IG51bWJlcjtcbiAgICBvdXRwdXRNdWx0aXBsaWVyOiBudW1iZXI7XG4gIH07XG59XG5cbi8vIOKUgOKUgCBPcGVuQUkg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG4vL1xuLy8gU3RhbmRhcmQgcHJpY2luZyB2ZXJpZmllZCAyMDI2LTA5LTIzICjquLDsobQg66qo6424IOuLqOqwgCDrs4Drj5kg7JeG7J2MKTogaHR0cHM6Ly9kZXZlbG9wZXJzLm9wZW5haS5jb20vYXBpL2RvY3MvcHJpY2luZ1xuLy8g7Iug66qo6424IOy2nOyLnOuniOuLpCDri6jqsIDqsIAg67CU64CM66+A66GcKDUuMuKGkjUuNOKGkjUuNSkg66qo6424IOy2lOqwgCDsi5wg67CY65Oc7IucIOqzteyLnSDtjpjsnbTsp4Ag7J6s7ZmV7J247ZW07JW87ZWoXG5cbi8vIEdQVC01LjTsl5DshJwg7LKY7J2MIOuPhOyeheuQnCBsb25nLWNvbnRleHQg7ZWg7KadICg1LjIvNS4zLWNvZGV464qUIO2VtOuLuSDsl4bsnYwsIDUuNC1taW5pL25hbm/ripQg6rO17IudIO2RnOyXkOyEnCBsb25nLWNvbnRleHQg64uo6rCAIOyXhuydjClcbi8vIDI3Mksg7LSI6rO8IOyLnCBpbnB1dCAyeCAvIGNhY2hlZCAyeCAvIG91dHB1dCAxLjV4IOKAlCDstIjqs7zrtoTrp4zsnbQg7JWE64uMIOyEuOyFmCDsoITssrTsl5Ag7KCB7Jqp65CoXG4vLyBAc2VlIGh0dHBzOi8vZGV2ZWxvcGVycy5vcGVuYWkuY29tL2FwaS9kb2NzL21vZGVscy9ncHQtNS41IChcInByb21wdHMgd2l0aCA+MjcySyBpbnB1dCB0b2tlbnNcIilcbmNvbnN0IExPTkdfQ09OVEVYVF8yNzJLOiBOb25OdWxsYWJsZTxNb2RlbENvc3RzW1wibG9uZ0NvbnRleHRcIl0+ID0ge1xuICB0aHJlc2hvbGQ6IDI3Ml8wMDAsXG4gIGlucHV0TXVsdGlwbGllcjogMixcbiAgY2FjaGVkSW5wdXRNdWx0aXBsaWVyOiAyLFxuICBvdXRwdXRNdWx0aXBsaWVyOiAxLjUsXG59O1xuXG4vLyBPcGVuQUkg66qo6424IOy5tO2DiOuhnOq3uC4g64uo6rCA7JmAIO2VqOq7mCBDb2RleCDrsLHsl5Trk5zqsIAg66qo642467OE66GcIOuwm+uKlCDstZzrjIAgcmVhc29uaW5nIGVmZm9ydCDrpbwg7ZWcIOqzs+yXkCDrkZTri6QuXG4vLyBtYXhFZmZvcnQg7Lac7LKYOiB+Ly5jb2RleC9tb2RlbHNfY2FjaGUuanNvbiDsnZggc3VwcG9ydGVkX3JlYXNvbmluZ19sZXZlbHMgKDIwMjYtMDktMDcg7ZmV7J24KS5cbi8vIOuvuOq4sOyerCDrqqjrjbjsnYAgeGhpZ2gg6rmM7KeA66eMIOuwm+uKlOuLpC5cbnR5cGUgT3BlbkFJTW9kZWxTcGVjID0gTW9kZWxDb3N0cyAmIHsgbWF4RWZmb3J0PzogT3BlbkFJRWZmb3J0IH07XG5cbmNvbnN0IE9QRU5BSV9DT1NUUzogUmVjb3JkPHN0cmluZywgT3BlbkFJTW9kZWxTcGVjPiA9IHtcbiAgLy8gR1BULTYgQXN0cmE6IFN0YW5kYXJkIEFQSS1lcXVpdmFsZW50IHByaWNpbmcsIHZlcmlmaWVkIDIwMjYtMDktMDcuXG4gIC8vIENvZGV4IHN1YnNjcmlwdGlvbiBjYXRhbG9nIHN1cHBvcnRzIHVsdHJhOyB0aGUgcHVibGljIEFQSSBsaXN0cyBvbmx5IHRocm91Z2ggbWF4LlxuICAvLyBAc2VlIGh0dHBzOi8vZGV2ZWxvcGVycy5vcGVuYWkuY29tL2FwaS9kb2NzL21vZGVscy9ncHQtNi1hc3RyYVxuICAvLyBAc2VlIGh0dHBzOi8vZGV2ZWxvcGVycy5vcGVuYWkuY29tL2FwaS9kb2NzL3ByaWNpbmdcbiAgXCJncHQtNi1hc3RyYVwiOiB7XG4gICAgbWF4RWZmb3J0OiBcInVsdHJhXCIsXG4gICAgaW5wdXRUb2tlbnM6IDEwLFxuICAgIG91dHB1dFRva2VuczogNTAsXG4gICAgY2FjaGVkSW5wdXRUb2tlbnM6IDEsXG4gICAgY2FjaGVDcmVhdGlvbklucHV0VG9rZW5zOiAxMi41LFxuICAgIGxvbmdDb250ZXh0OiBMT05HX0NPTlRFWFRfMjcySyxcbiAgfSxcbiAgLy8gR1BULTYuMSBTb2wgKDIwMjYtMDktMjkgRGV2RGF5IOy2nOyLnCk6IFN0YW5kYXJkIEFQSSBwcmljaW5nIHZlcmlmaWVkIDIwMjYtMDktMzAuIEdQVC02IFNvbCDqs7wg6rCZ6rOgIGNhY2hlZCBpbnB1dCDrp4wg7KCI67CYLlxuICAvLyBDb2RleCDsubTtg4jroZzqt7goMjAyNi0wOS0zMCnripQgdWx0cmEg6rmM7KeAIO2XiOyaqe2VmOqzoCDquLDrs7ggZWZmb3J0IOuKlCBsb3cg64ukKEdQVC02IFNvbCDsnYAgbWVkaXVtKS5cbiAgLy8gcWdyaWQg7J2YIOyalOyyrSDtmJXtg5wgKyBjb2RleF9jbGlfcnMvMC4xNDcuMCDtl6TrjZTroZwgMjAyNi0wOS0zMCDqtazrj4Ug6rK966GcIOudvOydtOu4jCDsg53shLEg7ISx6rO1LlxuICAvLyBAc2VlIGh0dHBzOi8vZGV2ZWxvcGVycy5vcGVuYWkuY29tL2FwaS9kb2NzL21vZGVscy9ncHQtNi4xLXNvbFxuICBcImdwdC02LjEtc29sXCI6IHtcbiAgICBtYXhFZmZvcnQ6IFwidWx0cmFcIixcbiAgICBpbnB1dFRva2VuczogMixcbiAgICBvdXRwdXRUb2tlbnM6IDEwLFxuICAgIGNhY2hlZElucHV0VG9rZW5zOiAwLjEsXG4gICAgY2FjaGVDcmVhdGlvbklucHV0VG9rZW5zOiAyLjUsXG4gICAgbG9uZ0NvbnRleHQ6IExPTkdfQ09OVEVYVF8yNzJLLFxuICB9LFxuICAvLyBHUFQtNiBTb2wsIEx1bmEgKDIwMjYtMDktMjIg7Lac7IucKTogU3RhbmRhcmQgQVBJIHByaWNpbmcgdmVyaWZpZWQgMjAyNi0wOS0yMy4gR1BULTUuNiBTb2wvTHVuYSDsnZgg7KCI67CYIOuLqOqwgC5cbiAgLy8gQ29kZXgg7Lm07YOI66Gc6re4KDIwMjYtMDktMjMp64qUIFNvbCDsl5AgdWx0cmEsIEx1bmEg7JeQIG1heCDquYzsp4Ag7ZeI7Jqp7ZWY6rOgIOq4sOuzuCBlZmZvcnQg64qUIOuRmCDri6QgbWVkaXVtIOydtOuLpC5cbiAgLy8gQHNlZSBodHRwczovL2RldmVsb3BlcnMub3BlbmFpLmNvbS9hcGkvZG9jcy9tb2RlbHMvZ3B0LTYtc29sXG4gIC8vIEBzZWUgaHR0cHM6Ly9kZXZlbG9wZXJzLm9wZW5haS5jb20vYXBpL2RvY3MvbW9kZWxzL2dwdC02LWx1bmFcbiAgXCJncHQtNi1zb2xcIjoge1xuICAgIG1heEVmZm9ydDogXCJ1bHRyYVwiLFxuICAgIGlucHV0VG9rZW5zOiAyLFxuICAgIG91dHB1dFRva2VuczogMTAsXG4gICAgY2FjaGVkSW5wdXRUb2tlbnM6IDAuMixcbiAgICBjYWNoZUNyZWF0aW9uSW5wdXRUb2tlbnM6IDIuNSxcbiAgICBsb25nQ29udGV4dDogTE9OR19DT05URVhUXzI3MkssXG4gIH0sXG4gIFwiZ3B0LTYtbHVuYVwiOiB7XG4gICAgbWF4RWZmb3J0OiBcIm1heFwiLFxuICAgIGlucHV0VG9rZW5zOiAwLjEsXG4gICAgb3V0cHV0VG9rZW5zOiAwLjUsXG4gICAgY2FjaGVkSW5wdXRUb2tlbnM6IDAuMDEsXG4gICAgY2FjaGVDcmVhdGlvbklucHV0VG9rZW5zOiAwLjEyNSxcbiAgICBsb25nQ29udGV4dDogTE9OR19DT05URVhUXzI3MkssXG4gIH0sXG4gIC8vIEdQVC01LjYgU29sLCBUZXJyYSwgTHVuYS4gY2FjaGUgd3JpdGUg64uo6rCA64qUIOyZuOu2gCBsb2dnZXIvbWFudWFsIHVzYWdlIOyeheugpeydhCDsnITtlbRcbiAgLy8g7Jyg7KeA7ZWc64ukLiDtmITsnqwgT3BlbkFJIOydkeuLtSB1c2FnZSDsl5AgY2FjaGUgd3JpdGUg7Yag7YGwIO2VhOuTnOqwgCDsl4bsnLzrqbQg67mE7Jqp7J2AIDDsnLzroZwg6rOE7IKw65Cc64ukLlxuICAvLyBAc2VlIGh0dHBzOi8vZGV2ZWxvcGVycy5vcGVuYWkuY29tL2FwaS9kb2NzL21vZGVscy9ncHQtNS42LXNvbFxuICAvLyBAc2VlIGh0dHBzOi8vZGV2ZWxvcGVycy5vcGVuYWkuY29tL2FwaS9kb2NzL21vZGVscy9ncHQtNS42LXRlcnJhXG4gIC8vIEBzZWUgaHR0cHM6Ly9kZXZlbG9wZXJzLm9wZW5haS5jb20vYXBpL2RvY3MvbW9kZWxzL2dwdC01LjYtbHVuYVxuICAvLyBTb2wgcHJvbW90aW9uYWwgcmF0ZXMgYXJlIGF2YWlsYWJsZSBhdCBsZWFzdCB0aHJvdWdoIDIwMjYtMTEtMjEuXG4gIC8vIE5vIGNvbmZpcm1lZCBlbmQgZGF0ZS9yZXBsYWNlbWVudCByYXRlOiByZWNoZWNrIG9mZmljaWFsIHByaWNpbmcgaW5zdGVhZCBvZiBhdXRvLXJldmVydGluZy5cbiAgXCJncHQtNS42LXNvbFwiOiB7XG4gICAgbWF4RWZmb3J0OiBcInVsdHJhXCIsXG4gICAgaW5wdXRUb2tlbnM6IDQsXG4gICAgb3V0cHV0VG9rZW5zOiAyMCxcbiAgICBjYWNoZWRJbnB1dFRva2VuczogMC40LFxuICAgIGNhY2hlQ3JlYXRpb25JbnB1dFRva2VuczogNSxcbiAgICBsb25nQ29udGV4dDogTE9OR19DT05URVhUXzI3MkssXG4gIH0sXG4gIFwiZ3B0LTUuNi10ZXJyYVwiOiB7XG4gICAgbWF4RWZmb3J0OiBcInVsdHJhXCIsXG4gICAgaW5wdXRUb2tlbnM6IDIsXG4gICAgb3V0cHV0VG9rZW5zOiAxMixcbiAgICBjYWNoZWRJbnB1dFRva2VuczogMC4yLFxuICAgIGNhY2hlQ3JlYXRpb25JbnB1dFRva2VuczogMi41LFxuICAgIGxvbmdDb250ZXh0OiBMT05HX0NPTlRFWFRfMjcySyxcbiAgfSxcbiAgXCJncHQtNS42LWx1bmFcIjoge1xuICAgIG1heEVmZm9ydDogXCJtYXhcIixcbiAgICBpbnB1dFRva2VuczogMC4yLFxuICAgIG91dHB1dFRva2VuczogMS4yLFxuICAgIGNhY2hlZElucHV0VG9rZW5zOiAwLjAyLFxuICAgIGNhY2hlQ3JlYXRpb25JbnB1dFRva2VuczogMC4yNSxcbiAgICBsb25nQ29udGV4dDogTE9OR19DT05URVhUXzI3MkssXG4gIH0sXG4gIC8vIGh0dHBzOi8vb3BlbmFpLmNvbS9pbmRleC9pbnRyb2R1Y2luZy1ncHQtNS01LyAoMjAyNi0wNCDstpzsi5wpXG4gIFwiZ3B0LTUuNVwiOiB7XG4gICAgaW5wdXRUb2tlbnM6IDUsXG4gICAgb3V0cHV0VG9rZW5zOiAzMCxcbiAgICBjYWNoZWRJbnB1dFRva2VuczogMC41LFxuICAgIGxvbmdDb250ZXh0OiBMT05HX0NPTlRFWFRfMjcySyxcbiAgfSxcbiAgLy8g7JWE656YIGdwdC01LjQgLyBncHQtNS40LW1pbmkgLyBncHQtNS4zLWNvZGV4IC8gZ3B0LTUuMiDripQgcWdyaWQg6rCAIOyTsOuKlCBDaGF0R1BUIOq1rOuPhSBDb2RleCDqsr3roZzsl5DshJxcbiAgLy8g642UIOydtOyDgSDsoJzqs7XrkJjsp4Ag7JWK64qU64ukKDUuNCDqs4Tsl7TsnYAgMjAyNi0wOC0zMSByZXRpcmVkLCDrjIDssrQgZ3B0LTUuNi10ZXJyYSAvIGdwdC01LjYtbHVuYSkuXG4gIC8vIOqzvOqxsCByZXF1ZXN0IGxvZyDsnqzsgrDsoJUoY29zdF9zb3VyY2Ug7JeG64qUIGxlZ2FjeSDtlokp7JeQIO2VhOyalO2VmOuvgOuhnCDri6jqsIAg7ZaJ7J2AIOycoOyngO2VnOuLpC5cbiAgLy8gaHR0cHM6Ly9vcGVuYWkuY29tL2luZGV4L2ludHJvZHVjaW5nLWdwdC01LTQvICgyMDI2LTAzIOy2nOyLnClcbiAgXCJncHQtNS40XCI6IHtcbiAgICBpbnB1dFRva2VuczogMi41LFxuICAgIG91dHB1dFRva2VuczogMTUsXG4gICAgY2FjaGVkSW5wdXRUb2tlbnM6IDAuMjUsXG4gICAgbG9uZ0NvbnRleHQ6IExPTkdfQ09OVEVYVF8yNzJLLFxuICB9LFxuICBcImdwdC01LjQtbWluaVwiOiB7IGlucHV0VG9rZW5zOiAwLjc1LCBvdXRwdXRUb2tlbnM6IDQuNSwgY2FjaGVkSW5wdXRUb2tlbnM6IDAuMDc1IH0sXG4gIC8vIGdwdC01LjLsmYAg64+Z7J28IOuLqOqwgCAoY2FjaGVkID0gaW5wdXTsnZggMTAlKVxuICBcImdwdC01LjMtY29kZXhcIjogeyBpbnB1dFRva2VuczogMS43NSwgb3V0cHV0VG9rZW5zOiAxNCwgY2FjaGVkSW5wdXRUb2tlbnM6IDAuMTc1IH0sXG4gIC8vIGh0dHBzOi8vb3BlbmFpLmNvbS9pbmRleC9pbnRyb2R1Y2luZy1ncHQtNS0yLyAoY2FjaGVkIGlucHV0IDkwJSDtlaDsnbgg66qF7IucKVxuICBcImdwdC01LjJcIjogeyBpbnB1dFRva2VuczogMS43NSwgb3V0cHV0VG9rZW5zOiAxNCwgY2FjaGVkSW5wdXRUb2tlbnM6IDAuMTc1IH0sXG59O1xuXG4vLyDilIDilIAgQW50aHJvcGljIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG5mdW5jdGlvbiBhbnRocm9waWNDb3N0cyhcbiAgaW5wdXRUb2tlbnM6IG51bWJlcixcbiAgb3V0cHV0VG9rZW5zOiBudW1iZXIsXG4gIG92ZXJyaWRlczogUGljazxQYXJ0aWFsPE1vZGVsQ29zdHM+LCBcImNhY2hlZElucHV0VG9rZW5zXCI+ID0ge30sXG4pOiBNb2RlbENvc3RzIHtcbiAgcmV0dXJuIHtcbiAgICBpbnB1dFRva2VucyxcbiAgICBvdXRwdXRUb2tlbnMsXG4gICAgLy8g7ZGc7KSAIGNhY2hlIHJlYWQg64qUIGJhc2UgaW5wdXQg7J2YIDAuMXguIEZhYmxlIDUuMSDsspjrn7wg6rO17IudIO2KueuhgCDri6jqsIDqsIAg7J6I7Jy866m0IG92ZXJyaWRlIO2VnOuLpC5cbiAgICBjYWNoZWRJbnB1dFRva2Vuczogb3ZlcnJpZGVzLmNhY2hlZElucHV0VG9rZW5zID8/IGlucHV0VG9rZW5zIC8gMTAsXG4gICAgLy8gQ2xhdWRlIENvZGUgc3Vic2NyaXB0aW9uIE9BdXRoIOuKlCAxaCBUVEwg7J2EIOyekOuPmSDshKDtg53tlZzri6QuIOq1rOuyhOyghOyymOufvCDsnZHri7Xsl5BcbiAgICAvLyBUVEwgYnJlYWtkb3duIOydtCDsl4bsnYQg65WM66eMIOydtCAxaCDri6jqsIDrpbwgZmFsbGJhY2sg7Jy866GcIOyCrOyaqe2VnOuLpC5cbiAgICBjYWNoZUNyZWF0aW9uSW5wdXRUb2tlbnM6IGlucHV0VG9rZW5zICogMixcbiAgICBjYWNoZUNyZWF0aW9uSW5wdXRUb2tlbnM1bTogaW5wdXRUb2tlbnMgKiAxLjI1LFxuICAgIGNhY2hlQ3JlYXRpb25JbnB1dFRva2VuczFoOiBpbnB1dFRva2VucyAqIDIsXG4gIH07XG59XG5cbi8vIOqwgOqyqSDstpzsspg6IGh0dHBzOi8vcGxhdGZvcm0uY2xhdWRlLmNvbS9kb2NzL2VuL2Fib3V0LWNsYXVkZS9wcmljaW5nICgyMDI2LTA5LTIzIO2ZleyduCwg6riw7KG0IOuqqOuNuCDri6jqsIAg67OA64+ZIOyXhuydjClcbmNvbnN0IEFOVEhST1BJQ19DT1NUUzogUmVjb3JkPHN0cmluZywgTW9kZWxDb3N0cz4gPSB7XG4gIC8vIEZhYmxlIDUuMSAoMjAyNi0wOS0wMSDstpzsi5wpOiBpbnB1dC9vdXRwdXQg7J2AIEZhYmxlIDUg7JmAIOqwmeqzoCBjYWNoZSByZWFkIOunjCAwLjAyNXgoJDAuMjUpIO2KueuhgC5cbiAgLy8gQHNlZSBodHRwczovL3BsYXRmb3JtLmNsYXVkZS5jb20vZG9jcy9lbi9tb2RlbHMvZmFibGUtNS0xL292ZXJ2aWV3XG4gIFwiY2xhdWRlLWZhYmxlLTUtMVwiOiBhbnRocm9waWNDb3N0cygxMCwgNTAsIHsgY2FjaGVkSW5wdXRUb2tlbnM6IDAuMjUgfSksXG4gIFwiY2xhdWRlLWZhYmxlLTVcIjogYW50aHJvcGljQ29zdHMoMTAsIDUwKSxcbiAgc29ubmV0OiBhbnRocm9waWNDb3N0cygzLCAxNSksXG4gIFwiY2xhdWRlLTMtNS1oYWlrdVwiOiBhbnRocm9waWNDb3N0cygwLjgsIDQpLFxuICBcImNsYXVkZS1oYWlrdS00LTVcIjogYW50aHJvcGljQ29zdHMoMSwgNSksXG4gIFwiY2xhdWRlLTMtNS1zb25uZXRcIjogYW50aHJvcGljQ29zdHMoMywgMTUpLFxuICBcImNsYXVkZS0zLTctc29ubmV0XCI6IGFudGhyb3BpY0Nvc3RzKDMsIDE1KSxcbiAgXCJjbGF1ZGUtc29ubmV0LTRcIjogYW50aHJvcGljQ29zdHMoMywgMTUpLFxuICBcImNsYXVkZS1zb25uZXQtNC01XCI6IGFudGhyb3BpY0Nvc3RzKDMsIDE1KSxcbiAgXCJjbGF1ZGUtc29ubmV0LTQtNlwiOiBhbnRocm9waWNDb3N0cygzLCAxNSksXG4gIFwiY2xhdWRlLXNvbm5ldC00LTdcIjogYW50aHJvcGljQ29zdHMoMywgMTUpLFxuICBcImNsYXVkZS1vcHVzLTRcIjogYW50aHJvcGljQ29zdHMoMTUsIDc1KSxcbiAgXCJjbGF1ZGUtb3B1cy00LTFcIjogYW50aHJvcGljQ29zdHMoMTUsIDc1KSxcbiAgXCJjbGF1ZGUtb3B1cy00LTVcIjogYW50aHJvcGljQ29zdHMoNSwgMjUpLFxuICBcImNsYXVkZS1vcHVzLTQtNlwiOiBhbnRocm9waWNDb3N0cyg1LCAyNSksXG4gIFwiY2xhdWRlLW9wdXMtNC03XCI6IGFudGhyb3BpY0Nvc3RzKDUsIDI1KSxcbiAgXCJjbGF1ZGUtb3B1cy00LThcIjogYW50aHJvcGljQ29zdHMoNSwgMjUpLFxuICBcImNsYXVkZS1vcHVzLTVcIjogYW50aHJvcGljQ29zdHMoNSwgMjUpLFxuICAvLyBPcHVzIDUuNSAoMjAyNi0wOS0yMiDstpzsi5wpOiAkNC8kMjAuIGNhY2hlIHJlYWQg64qUIDAuMDV4KCQwLjIwKSDtirnroYAsIGNhY2hlIHdyaXRlIOuKlCDtkZzspIAg67Cw7JyoKCQ1LyQ4KS5cbiAgLy8gQHNlZSBodHRwczovL3BsYXRmb3JtLmNsYXVkZS5jb20vZG9jcy9lbi9tb2RlbHMvb3B1cy01LTUvb3ZlcnZpZXdcbiAgXCJjbGF1ZGUtb3B1cy01LTVcIjogYW50aHJvcGljQ29zdHMoNCwgMjAsIHsgY2FjaGVkSW5wdXRUb2tlbnM6IDAuMiB9KSxcbiAgLy8gU29ubmV0IDUg7J2YIGludHJvZHVjdG9yeSAkMi8kMTAg7J20IOygleyLnSDri6jqsIDroZwg7ZmV7KCV65CQ64ukLiAyMDI2LTA5LTAxIOyXkCDsmIjsoJXrkJDrjZggJDMvJDE1IOyduOyDgeydgFxuICAvLyDst6jshozrkJDsnLzrr4DroZwg64Kg7KecIOu2hOq4sCDsl4bsnbQg6rOg7KCVIOuLqOqwgOuhnCDqs4TsgrDtlZzri6QuXG4gIFwiY2xhdWRlLXNvbm5ldC01XCI6IGFudGhyb3BpY0Nvc3RzKDIsIDEwKSxcbiAgLy8gU29ubmV0IDUuNSAoMjAyNi0wOS0yOSDstpzsi5wpOiBTb25uZXQgNSDsmYAg6rCZ7J2AICQyLyQxMCwgY2FjaGUgcmVhZCDripQg7ZGc7KSAIDAuMXgoJDAuMjApLlxuICAvLyBAc2VlIGh0dHBzOi8vcGxhdGZvcm0uY2xhdWRlLmNvbS9kb2NzL2VuL2Fib3V0LWNsYXVkZS9wcmljaW5nXG4gIFwiY2xhdWRlLXNvbm5ldC01LTVcIjogYW50aHJvcGljQ29zdHMoMiwgMTApLFxufTtcblxuLy8gZ3B0LTUuMy1jb2RleC1zcGFyayDripQgcmVzZWFyY2ggcHJldmlldyDroZwg6rO17IudIHRva2VuIOuLqOqwgOqwgCDslYTsp4EgZmluYWwg7J20IOyVhOuLiOuLpC5cbi8vIOyngOybkCDtg4DsnoXsnYAg7Jyg7KeA7ZWY65CYLCDqs7Xsi50g64uo6rCA6rCAIOqzteqwnOuQoCDrlYzquYzsp4Ag7JWE656YIGdlbmVyaWMgZXN0aW1hdGUg66GcIOqzhOyCsO2VnOuLpC5cbi8vIEBzZWUgaHR0cHM6Ly9oZWxwLm9wZW5haS5jb20vZW4vYXJ0aWNsZXMvMjAwMDExMDYtY29kZXgtcmF0ZS1jYXJkXG5jb25zdCBERUZBVUxUX0NPU1RTOiBNb2RlbENvc3RzID0geyBpbnB1dFRva2VuczogMywgb3V0cHV0VG9rZW5zOiAxNSwgY2FjaGVkSW5wdXRUb2tlbnM6IDAuMyB9O1xuXG4vKiogQ29kZXgg67Cx7JeU65Oc6rCAIOydtCDrqqjrjbjsl5Ag7ZeI7Jqp7ZWY64qUIOy1nOuMgCBlZmZvcnQuIOy5tO2DiOuhnOq3uOyXkCDsl4bripQg66qo64247J2AIHhoaWdoIOq5jOyngOuLpC4gKi9cbmV4cG9ydCBmdW5jdGlvbiBvcGVuYWlNb2RlbE1heEVmZm9ydChtb2RlbDogc3RyaW5nKTogT3BlbkFJRWZmb3J0IHtcbiAgcmV0dXJuIE9QRU5BSV9DT1NUU1ttb2RlbF0/Lm1heEVmZm9ydCA/PyBcInhoaWdoXCI7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRNb2RlbENvc3RzKG1vZGVsOiBzdHJpbmcpOiBNb2RlbENvc3RzIHtcbiAgY29uc3Qgbm9ybWFsaXplZE1vZGVsID0gKG1vZGVsLnNwbGl0KFwiL1wiKS5wb3AoKSA/PyBtb2RlbCkucmVwbGFjZSgvXFxbMW1cXF0kL2ksIFwiXCIpO1xuICByZXR1cm4gT1BFTkFJX0NPU1RTW25vcm1hbGl6ZWRNb2RlbF0gPz8gQU5USFJPUElDX0NPU1RTW25vcm1hbGl6ZWRNb2RlbF0gPz8gREVGQVVMVF9DT1NUUztcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNhbGN1bGF0ZUNvc3RVc2QoXG4gIG1vZGVsOiBzdHJpbmcsXG4gIHVzYWdlOiB7XG4gICAgaW5wdXRUb2tlbnM6IG51bWJlcjtcbiAgICBvdXRwdXRUb2tlbnM6IG51bWJlcjtcbiAgICBjYWNoZWRJbnB1dFRva2Vucz86IG51bWJlcjtcbiAgICBjYWNoZUNyZWF0aW9uSW5wdXRUb2tlbnM/OiBudW1iZXI7XG4gICAgY2FjaGVDcmVhdGlvbklucHV0VG9rZW5zNW0/OiBudW1iZXI7XG4gICAgY2FjaGVDcmVhdGlvbklucHV0VG9rZW5zMWg/OiBudW1iZXI7XG4gIH0sXG4pOiBudW1iZXIge1xuICBjb25zdCBjb3N0cyA9IGdldE1vZGVsQ29zdHMobW9kZWwpO1xuICBjb25zdCBjYWNoZWRJbnB1dCA9IHVzYWdlLmNhY2hlZElucHV0VG9rZW5zID8/IDA7XG4gIGNvbnN0IGNhY2hlQ3JlYXRpb25JbnB1dDVtID0gTWF0aC5tYXgodXNhZ2UuY2FjaGVDcmVhdGlvbklucHV0VG9rZW5zNW0gPz8gMCwgMCk7XG4gIGNvbnN0IGNhY2hlQ3JlYXRpb25JbnB1dDFoID0gTWF0aC5tYXgodXNhZ2UuY2FjaGVDcmVhdGlvbklucHV0VG9rZW5zMWggPz8gMCwgMCk7XG4gIGNvbnN0IGNhY2hlQ3JlYXRpb25JbnB1dCA9IE1hdGgubWF4KFxuICAgIHVzYWdlLmNhY2hlQ3JlYXRpb25JbnB1dFRva2VucyA/PyAwLFxuICAgIGNhY2hlQ3JlYXRpb25JbnB1dDVtICsgY2FjaGVDcmVhdGlvbklucHV0MWgsXG4gICk7XG4gIGNvbnN0IGNsYXNzaWZpZWRDYWNoZUNyZWF0aW9uSW5wdXQ1bSA9IE1hdGgubWluKGNhY2hlQ3JlYXRpb25JbnB1dDVtLCBjYWNoZUNyZWF0aW9uSW5wdXQpO1xuICBjb25zdCBjbGFzc2lmaWVkQ2FjaGVDcmVhdGlvbklucHV0MWggPSBNYXRoLm1pbihcbiAgICBjYWNoZUNyZWF0aW9uSW5wdXQxaCxcbiAgICBjYWNoZUNyZWF0aW9uSW5wdXQgLSBjbGFzc2lmaWVkQ2FjaGVDcmVhdGlvbklucHV0NW0sXG4gICk7XG4gIGNvbnN0IHVuY2xhc3NpZmllZENhY2hlQ3JlYXRpb25JbnB1dCA9XG4gICAgY2FjaGVDcmVhdGlvbklucHV0IC0gY2xhc3NpZmllZENhY2hlQ3JlYXRpb25JbnB1dDVtIC0gY2xhc3NpZmllZENhY2hlQ3JlYXRpb25JbnB1dDFoO1xuICBjb25zdCBub25DYWNoZWRJbnB1dCA9IE1hdGgubWF4KHVzYWdlLmlucHV0VG9rZW5zIC0gY2FjaGVkSW5wdXQgLSBjYWNoZUNyZWF0aW9uSW5wdXQsIDApO1xuXG4gIC8vIGxvbmctY29udGV4dCDtlaDspp06IOyghOyytCDsnoXroKUoaW5wdXRfdG9rZW5zLCBjYWNoZSDtj6ztlagp7J20IHRocmVzaG9sZCDstIjqs7wg7IucIOyalOyyrSDsoITssrTsl5Ag67Cw7JyoIOyggeyaqVxuICBjb25zdCBsYyA9IGNvc3RzLmxvbmdDb250ZXh0O1xuICBjb25zdCBpc0xvbmdDb250ZXh0ID0gbGMgIT09IHVuZGVmaW5lZCAmJiB1c2FnZS5pbnB1dFRva2VucyA+IGxjLnRocmVzaG9sZDtcbiAgY29uc3QgaW5wdXRSYXRlID0gY29zdHMuaW5wdXRUb2tlbnMgKiAoaXNMb25nQ29udGV4dCA/IGxjLmlucHV0TXVsdGlwbGllciA6IDEpO1xuICBjb25zdCBjYWNoZWRSYXRlID0gY29zdHMuY2FjaGVkSW5wdXRUb2tlbnMgKiAoaXNMb25nQ29udGV4dCA/IGxjLmNhY2hlZElucHV0TXVsdGlwbGllciA6IDEpO1xuICBjb25zdCBjYWNoZUNyZWF0aW9uRmFsbGJhY2tSYXRlID1cbiAgICAoY29zdHMuY2FjaGVDcmVhdGlvbklucHV0VG9rZW5zID8/IGNvc3RzLmlucHV0VG9rZW5zKSAqXG4gICAgKGlzTG9uZ0NvbnRleHQgPyBsYy5pbnB1dE11bHRpcGxpZXIgOiAxKTtcbiAgY29uc3QgY2FjaGVDcmVhdGlvbjVtUmF0ZSA9XG4gICAgKGNvc3RzLmNhY2hlQ3JlYXRpb25JbnB1dFRva2VuczVtID8/IGNvc3RzLmNhY2hlQ3JlYXRpb25JbnB1dFRva2VucyA/PyBjb3N0cy5pbnB1dFRva2VucykgKlxuICAgIChpc0xvbmdDb250ZXh0ID8gbGMuaW5wdXRNdWx0aXBsaWVyIDogMSk7XG4gIGNvbnN0IGNhY2hlQ3JlYXRpb24xaFJhdGUgPVxuICAgIChjb3N0cy5jYWNoZUNyZWF0aW9uSW5wdXRUb2tlbnMxaCA/PyBjb3N0cy5jYWNoZUNyZWF0aW9uSW5wdXRUb2tlbnMgPz8gY29zdHMuaW5wdXRUb2tlbnMpICpcbiAgICAoaXNMb25nQ29udGV4dCA/IGxjLmlucHV0TXVsdGlwbGllciA6IDEpO1xuICBjb25zdCBvdXRwdXRSYXRlID0gY29zdHMub3V0cHV0VG9rZW5zICogKGlzTG9uZ0NvbnRleHQgPyBsYy5vdXRwdXRNdWx0aXBsaWVyIDogMSk7XG5cbiAgcmV0dXJuIChcbiAgICAobm9uQ2FjaGVkSW5wdXQgLyAxXzAwMF8wMDApICogaW5wdXRSYXRlICtcbiAgICAodXNhZ2Uub3V0cHV0VG9rZW5zIC8gMV8wMDBfMDAwKSAqIG91dHB1dFJhdGUgK1xuICAgIChjYWNoZWRJbnB1dCAvIDFfMDAwXzAwMCkgKiBjYWNoZWRSYXRlICtcbiAgICAodW5jbGFzc2lmaWVkQ2FjaGVDcmVhdGlvbklucHV0IC8gMV8wMDBfMDAwKSAqIGNhY2hlQ3JlYXRpb25GYWxsYmFja1JhdGUgK1xuICAgIChjbGFzc2lmaWVkQ2FjaGVDcmVhdGlvbklucHV0NW0gLyAxXzAwMF8wMDApICogY2FjaGVDcmVhdGlvbjVtUmF0ZSArXG4gICAgKGNsYXNzaWZpZWRDYWNoZUNyZWF0aW9uSW5wdXQxaCAvIDFfMDAwXzAwMCkgKiBjYWNoZUNyZWF0aW9uMWhSYXRlXG4gICk7XG59XG4iXSwibWFwcGluZ3MiOiI7QUEwQ0EsTUFBTSxvQkFBNEQ7Q0FDaEUsV0FBVztDQUNYLGlCQUFpQjtDQUNqQix1QkFBdUI7Q0FDdkIsa0JBQWtCO0FBQ3BCO0FBT0EsTUFBTSxlQUFnRDtDQUtwRCxlQUFlO0VBQ2IsV0FBVztFQUNYLGFBQWE7RUFDYixjQUFjO0VBQ2QsbUJBQW1CO0VBQ25CLDBCQUEwQjtFQUMxQixhQUFhO0NBQ2Y7Q0FLQSxlQUFlO0VBQ2IsV0FB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
169
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9kZWwtY29zdC5qcyIsIm5hbWVzIjpbXSwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvdXRpbHMvcHJvdmlkZXJzL2NvbW1vbi9tb2RlbC1jb3N0LnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICog66qo642467OEIO2GoO2BsCDqsIDqsqkg7YWM7J2067iUICsgY29zdCDqs4TsgrAuXG4gKlxuICogY2xhdWRlIGNvZGUg7JmAIOuPmeydvCDtjKjthLQ6IO2BtOudvOydtOyWuO2KuOyXkOyEnCDqsIDqsqkg7YWM7J2067iU66GcIOyngeygkSDqs4TsgrAuXG4gKiDqsIDqsqkg64uo7JyEOiBVU0QgcGVyIDFNIHRva2Vucy5cbiAqXG4gKiBPcGVuQUkg66qo6424IOuqqeuhneydgCBPcGVuQUkg66qo6424IOusuOyEnOyZgCDtmITsnqwg7KeA7JuQIOuqqeuhneydhCDquLDspIDsnLzroZwg6rSA66as7ZWc64ukLlxuICpcbiAqIEBzZWUgaHR0cHM6Ly9wbGF0Zm9ybS5vcGVuYWkuY29tL2RvY3MvcHJpY2luZ1xuICogQHNlZSBodHRwczovL3BsYXRmb3JtLmNsYXVkZS5jb20vZG9jcy9lbi9hYm91dC1jbGF1ZGUvcHJpY2luZ1xuICovXG5cbmltcG9ydCB7IHR5cGUgT3BlbkFJRWZmb3J0IH0gZnJvbSBcIi4vZWZmb3J0XCI7XG5cbmV4cG9ydCBpbnRlcmZhY2UgTW9kZWxDb3N0cyB7XG4gIGlucHV0VG9rZW5zOiBudW1iZXI7XG4gIG91dHB1dFRva2VuczogbnVtYmVyO1xuICBjYWNoZWRJbnB1dFRva2VuczogbnVtYmVyO1xuICAvKiogVFRMIGJyZWFrZG93biDsnbQg7JeG64qUIHVzYWdlIOyXkCDsoIHsmqntlaAgY2FjaGUgd3JpdGUgZmFsbGJhY2sg64uo6rCALiAqL1xuICBjYWNoZUNyZWF0aW9uSW5wdXRUb2tlbnM/OiBudW1iZXI7XG4gIGNhY2hlQ3JlYXRpb25JbnB1dFRva2VuczVtPzogbnVtYmVyO1xuICBjYWNoZUNyZWF0aW9uSW5wdXRUb2tlbnMxaD86IG51bWJlcjtcbiAgLyoqXG4gICAqIGxvbmctY29udGV4dCDtlaDspp0uIOyghOyytCDsnoXroKUg7Yag7YGwKGlucHV0X3Rva2VucywgY2FjaGVfcmVhZCDtj6ztlagp7J20IHRocmVzaG9sZCDstIjqs7wg7IucXG4gICAqIOy0iOqzvOu2hOunjOydtCDslYTri4jrnbwg7JqU7LKtIOyghOyytChmdWxsIHNlc3Npb24p7JeQIOuwsOycqCDsoIHsmqkuXG4gICAqL1xuICBsb25nQ29udGV4dD86IHtcbiAgICB0aHJlc2hvbGQ6IG51bWJlcjtcbiAgICBpbnB1dE11bHRpcGxpZXI6IG51bWJlcjtcbiAgICBjYWNoZWRJbnB1dE11bHRpcGxpZXI6IG51bWJlcjtcbiAgICBvdXRwdXRNdWx0aXBsaWVyOiBudW1iZXI7XG4gIH07XG59XG5cbi8vIOKUgOKUgCBPcGVuQUkg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG4vL1xuLy8gU3RhbmRhcmQgcHJpY2luZyB2ZXJpZmllZCAyMDI2LTA5LTIzICjquLDsobQg66qo6424IOuLqOqwgCDrs4Drj5kg7JeG7J2MKTogaHR0cHM6Ly9kZXZlbG9wZXJzLm9wZW5haS5jb20vYXBpL2RvY3MvcHJpY2luZ1xuLy8g7Iug66qo6424IOy2nOyLnOuniOuLpCDri6jqsIDqsIAg67CU64CM66+A66GcKDUuMuKGkjUuNOKGkjUuNSkg66qo6424IOy2lOqwgCDsi5wg67CY65Oc7IucIOqzteyLnSDtjpjsnbTsp4Ag7J6s7ZmV7J247ZW07JW87ZWoXG5cbi8vIEdQVC01LjTsl5DshJwg7LKY7J2MIOuPhOyeheuQnCBsb25nLWNvbnRleHQg7ZWg7KadICg1LjIvNS4zLWNvZGV464qUIO2VtOuLuSDsl4bsnYwsIDUuNC1taW5pL25hbm/ripQg6rO17IudIO2RnOyXkOyEnCBsb25nLWNvbnRleHQg64uo6rCAIOyXhuydjClcbi8vIDI3Mksg7LSI6rO8IOyLnCBpbnB1dCAyeCAvIGNhY2hlZCAyeCAvIG91dHB1dCAxLjV4IOKAlCDstIjqs7zrtoTrp4zsnbQg7JWE64uMIOyEuOyFmCDsoITssrTsl5Ag7KCB7Jqp65CoXG4vLyBAc2VlIGh0dHBzOi8vZGV2ZWxvcGVycy5vcGVuYWkuY29tL2FwaS9kb2NzL21vZGVscy9ncHQtNS41IChcInByb21wdHMgd2l0aCA+MjcySyBpbnB1dCB0b2tlbnNcIilcbmNvbnN0IExPTkdfQ09OVEVYVF8yNzJLOiBOb25OdWxsYWJsZTxNb2RlbENvc3RzW1wibG9uZ0NvbnRleHRcIl0+ID0ge1xuICB0aHJlc2hvbGQ6IDI3Ml8wMDAsXG4gIGlucHV0TXVsdGlwbGllcjogMixcbiAgY2FjaGVkSW5wdXRNdWx0aXBsaWVyOiAyLFxuICBvdXRwdXRNdWx0aXBsaWVyOiAxLjUsXG59O1xuXG4vLyBPcGVuQUkg66qo6424IOy5tO2DiOuhnOq3uC4g64uo6rCA7JmAIO2VqOq7mCBDb2RleCDrsLHsl5Trk5zqsIAg66qo642467OE66GcIOuwm+uKlCDstZzrjIAgcmVhc29uaW5nIGVmZm9ydCDrpbwg7ZWcIOqzs+yXkCDrkZTri6QuXG4vLyBtYXhFZmZvcnQg7Lac7LKYOiB+Ly5jb2RleC9tb2RlbHNfY2FjaGUuanNvbiDsnZggc3VwcG9ydGVkX3JlYXNvbmluZ19sZXZlbHMgKDIwMjYtMDktMDcg7ZmV7J24KS5cbi8vIOuvuOq4sOyerCDrqqjrjbjsnYAgeGhpZ2gg6rmM7KeA66eMIOuwm+uKlOuLpC5cbnR5cGUgT3BlbkFJTW9kZWxTcGVjID0gTW9kZWxDb3N0cyAmIHsgbWF4RWZmb3J0PzogT3BlbkFJRWZmb3J0IH07XG5cbmNvbnN0IE9QRU5BSV9DT1NUUzogUmVjb3JkPHN0cmluZywgT3BlbkFJTW9kZWxTcGVjPiA9IHtcbiAgLy8gR1BULTYgQXN0cmE6IFN0YW5kYXJkIEFQSS1lcXVpdmFsZW50IHByaWNpbmcsIHZlcmlmaWVkIDIwMjYtMDktMDcuXG4gIC8vIENvZGV4IHN1YnNjcmlwdGlvbiBjYXRhbG9nIHN1cHBvcnRzIHVsdHJhOyB0aGUgcHVibGljIEFQSSBsaXN0cyBvbmx5IHRocm91Z2ggbWF4LlxuICAvLyBAc2VlIGh0dHBzOi8vZGV2ZWxvcGVycy5vcGVuYWkuY29tL2FwaS9kb2NzL21vZGVscy9ncHQtNi1hc3RyYVxuICAvLyBAc2VlIGh0dHBzOi8vZGV2ZWxvcGVycy5vcGVuYWkuY29tL2FwaS9kb2NzL3ByaWNpbmdcbiAgXCJncHQtNi1hc3RyYVwiOiB7XG4gICAgbWF4RWZmb3J0OiBcInVsdHJhXCIsXG4gICAgaW5wdXRUb2tlbnM6IDEwLFxuICAgIG91dHB1dFRva2VuczogNTAsXG4gICAgY2FjaGVkSW5wdXRUb2tlbnM6IDEsXG4gICAgY2FjaGVDcmVhdGlvbklucHV0VG9rZW5zOiAxMi41LFxuICAgIGxvbmdDb250ZXh0OiBMT05HX0NPTlRFWFRfMjcySyxcbiAgfSxcbiAgLy8gR1BULTYuMSBTb2wgKDIwMjYtMDktMjkgRGV2RGF5IOy2nOyLnCk6IFN0YW5kYXJkIEFQSSBwcmljaW5nIHZlcmlmaWVkIDIwMjYtMDktMzAuIEdQVC02IFNvbCDqs7wg6rCZ6rOgIGNhY2hlZCBpbnB1dCDrp4wg7KCI67CYLlxuICAvLyBDb2RleCDsubTtg4jroZzqt7goMjAyNi0wOS0zMCnripQgdWx0cmEg6rmM7KeAIO2XiOyaqe2VmOqzoCDquLDrs7ggZWZmb3J0IOuKlCBsb3cg64ukKEdQVC02IFNvbCDsnYAgbWVkaXVtKS5cbiAgLy8gcWdyaWQg7J2YIOyalOyyrSDtmJXtg5wgKyBjb2RleF9jbGlfcnMvMC4xNDcuMCDtl6TrjZTroZwgMjAyNi0wOS0zMCDqtazrj4Ug6rK966GcIOudvOydtOu4jCDsg53shLEg7ISx6rO1LlxuICAvLyBAc2VlIGh0dHBzOi8vZGV2ZWxvcGVycy5vcGVuYWkuY29tL2FwaS9kb2NzL21vZGVscy9ncHQtNi4xLXNvbFxuICBcImdwdC02LjEtc29sXCI6IHtcbiAgICBtYXhFZmZvcnQ6IFwidWx0cmFcIixcbiAgICBpbnB1dFRva2VuczogMixcbiAgICBvdXRwdXRUb2tlbnM6IDEwLFxuICAgIGNhY2hlZElucHV0VG9rZW5zOiAwLjEsXG4gICAgY2FjaGVDcmVhdGlvbklucHV0VG9rZW5zOiAyLjUsXG4gICAgbG9uZ0NvbnRleHQ6IExPTkdfQ09OVEVYVF8yNzJLLFxuICB9LFxuICAvLyBHUFQtNiBTb2wsIEx1bmEgKDIwMjYtMDktMjIg7Lac7IucKTogU3RhbmRhcmQgQVBJIHByaWNpbmcgdmVyaWZpZWQgMjAyNi0wOS0yMy4gR1BULTUuNiBTb2wvTHVuYSDsnZgg7KCI67CYIOuLqOqwgC5cbiAgLy8gQ29kZXgg7Lm07YOI66Gc6re4KDIwMjYtMDktMjMp64qUIFNvbCDsl5AgdWx0cmEsIEx1bmEg7JeQIG1heCDquYzsp4Ag7ZeI7Jqp7ZWY6rOgIOq4sOuzuCBlZmZvcnQg64qUIOuRmCDri6QgbWVkaXVtIOydtOuLpC5cbiAgLy8gQHNlZSBodHRwczovL2RldmVsb3BlcnMub3BlbmFpLmNvbS9hcGkvZG9jcy9tb2RlbHMvZ3B0LTYtc29sXG4gIC8vIEBzZWUgaHR0cHM6Ly9kZXZlbG9wZXJzLm9wZW5haS5jb20vYXBpL2RvY3MvbW9kZWxzL2dwdC02LWx1bmFcbiAgXCJncHQtNi1zb2xcIjoge1xuICAgIG1heEVmZm9ydDogXCJ1bHRyYVwiLFxuICAgIGlucHV0VG9rZW5zOiAyLFxuICAgIG91dHB1dFRva2VuczogMTAsXG4gICAgY2FjaGVkSW5wdXRUb2tlbnM6IDAuMixcbiAgICBjYWNoZUNyZWF0aW9uSW5wdXRUb2tlbnM6IDIuNSxcbiAgICBsb25nQ29udGV4dDogTE9OR19DT05URVhUXzI3MkssXG4gIH0sXG4gIFwiZ3B0LTYtbHVuYVwiOiB7XG4gICAgbWF4RWZmb3J0OiBcIm1heFwiLFxuICAgIGlucHV0VG9rZW5zOiAwLjEsXG4gICAgb3V0cHV0VG9rZW5zOiAwLjUsXG4gICAgY2FjaGVkSW5wdXRUb2tlbnM6IDAuMDEsXG4gICAgY2FjaGVDcmVhdGlvbklucHV0VG9rZW5zOiAwLjEyNSxcbiAgICBsb25nQ29udGV4dDogTE9OR19DT05URVhUXzI3MkssXG4gIH0sXG4gIC8vIEdQVC01LjYgU29sLCBUZXJyYSwgTHVuYS4gY2FjaGUgd3JpdGUg64uo6rCA64qUIOyZuOu2gCBsb2dnZXIvbWFudWFsIHVzYWdlIOyeheugpeydhCDsnITtlbRcbiAgLy8g7Jyg7KeA7ZWc64ukLiDtmITsnqwgT3BlbkFJIOydkeuLtSB1c2FnZSDsl5AgY2FjaGUgd3JpdGUg7Yag7YGwIO2VhOuTnOqwgCDsl4bsnLzrqbQg67mE7Jqp7J2AIDDsnLzroZwg6rOE7IKw65Cc64ukLlxuICAvLyBAc2VlIGh0dHBzOi8vZGV2ZWxvcGVycy5vcGVuYWkuY29tL2FwaS9kb2NzL21vZGVscy9ncHQtNS42LXNvbFxuICAvLyBAc2VlIGh0dHBzOi8vZGV2ZWxvcGVycy5vcGVuYWkuY29tL2FwaS9kb2NzL21vZGVscy9ncHQtNS42LXRlcnJhXG4gIC8vIEBzZWUgaHR0cHM6Ly9kZXZlbG9wZXJzLm9wZW5haS5jb20vYXBpL2RvY3MvbW9kZWxzL2dwdC01LjYtbHVuYVxuICAvLyBTb2wgcHJvbW90aW9uYWwgcmF0ZXMgYXJlIGF2YWlsYWJsZSBhdCBsZWFzdCB0aHJvdWdoIDIwMjYtMTEtMjEuXG4gIC8vIE5vIGNvbmZpcm1lZCBlbmQgZGF0ZS9yZXBsYWNlbWVudCByYXRlOiByZWNoZWNrIG9mZmljaWFsIHByaWNpbmcgaW5zdGVhZCBvZiBhdXRvLXJldmVydGluZy5cbiAgXCJncHQtNS42LXNvbFwiOiB7XG4gICAgbWF4RWZmb3J0OiBcInVsdHJhXCIsXG4gICAgaW5wdXRUb2tlbnM6IDQsXG4gICAgb3V0cHV0VG9rZW5zOiAyMCxcbiAgICBjYWNoZWRJbnB1dFRva2VuczogMC40LFxuICAgIGNhY2hlQ3JlYXRpb25JbnB1dFRva2VuczogNSxcbiAgICBsb25nQ29udGV4dDogTE9OR19DT05URVhUXzI3MkssXG4gIH0sXG4gIFwiZ3B0LTUuNi10ZXJyYVwiOiB7XG4gICAgbWF4RWZmb3J0OiBcInVsdHJhXCIsXG4gICAgaW5wdXRUb2tlbnM6IDIsXG4gICAgb3V0cHV0VG9rZW5zOiAxMixcbiAgICBjYWNoZWRJbnB1dFRva2VuczogMC4yLFxuICAgIGNhY2hlQ3JlYXRpb25JbnB1dFRva2VuczogMi41LFxuICAgIGxvbmdDb250ZXh0OiBMT05HX0NPTlRFWFRfMjcySyxcbiAgfSxcbiAgXCJncHQtNS42LWx1bmFcIjoge1xuICAgIG1heEVmZm9ydDogXCJtYXhcIixcbiAgICBpbnB1dFRva2VuczogMC4yLFxuICAgIG91dHB1dFRva2VuczogMS4yLFxuICAgIGNhY2hlZElucHV0VG9rZW5zOiAwLjAyLFxuICAgIGNhY2hlQ3JlYXRpb25JbnB1dFRva2VuczogMC4yNSxcbiAgICBsb25nQ29udGV4dDogTE9OR19DT05URVhUXzI3MkssXG4gIH0sXG4gIC8vIGh0dHBzOi8vb3BlbmFpLmNvbS9pbmRleC9pbnRyb2R1Y2luZy1ncHQtNS01LyAoMjAyNi0wNCDstpzsi5wpXG4gIFwiZ3B0LTUuNVwiOiB7XG4gICAgaW5wdXRUb2tlbnM6IDUsXG4gICAgb3V0cHV0VG9rZW5zOiAzMCxcbiAgICBjYWNoZWRJbnB1dFRva2VuczogMC41LFxuICAgIGxvbmdDb250ZXh0OiBMT05HX0NPTlRFWFRfMjcySyxcbiAgfSxcbiAgLy8g7JWE656YIGdwdC01LjQgLyBncHQtNS40LW1pbmkgLyBncHQtNS4zLWNvZGV4IC8gZ3B0LTUuMiDripQgcWdyaWQg6rCAIOyTsOuKlCBDaGF0R1BUIOq1rOuPhSBDb2RleCDqsr3roZzsl5DshJxcbiAgLy8g642UIOydtOyDgSDsoJzqs7XrkJjsp4Ag7JWK64qU64ukKDUuNCDqs4Tsl7TsnYAgMjAyNi0wOC0zMSByZXRpcmVkLCDrjIDssrQgZ3B0LTUuNi10ZXJyYSAvIGdwdC01LjYtbHVuYSkuXG4gIC8vIOqzvOqxsCByZXF1ZXN0IGxvZyDsnqzsgrDsoJUoY29zdF9zb3VyY2Ug7JeG64qUIGxlZ2FjeSDtlokp7JeQIO2VhOyalO2VmOuvgOuhnCDri6jqsIAg7ZaJ7J2AIOycoOyngO2VnOuLpC5cbiAgLy8gaHR0cHM6Ly9vcGVuYWkuY29tL2luZGV4L2ludHJvZHVjaW5nLWdwdC01LTQvICgyMDI2LTAzIOy2nOyLnClcbiAgXCJncHQtNS40XCI6IHtcbiAgICBpbnB1dFRva2VuczogMi41LFxuICAgIG91dHB1dFRva2VuczogMTUsXG4gICAgY2FjaGVkSW5wdXRUb2tlbnM6IDAuMjUsXG4gICAgbG9uZ0NvbnRleHQ6IExPTkdfQ09OVEVYVF8yNzJLLFxuICB9LFxuICBcImdwdC01LjQtbWluaVwiOiB7IGlucHV0VG9rZW5zOiAwLjc1LCBvdXRwdXRUb2tlbnM6IDQuNSwgY2FjaGVkSW5wdXRUb2tlbnM6IDAuMDc1IH0sXG4gIC8vIGdwdC01LjLsmYAg64+Z7J28IOuLqOqwgCAoY2FjaGVkID0gaW5wdXTsnZggMTAlKVxuICBcImdwdC01LjMtY29kZXhcIjogeyBpbnB1dFRva2VuczogMS43NSwgb3V0cHV0VG9rZW5zOiAxNCwgY2FjaGVkSW5wdXRUb2tlbnM6IDAuMTc1IH0sXG4gIC8vIGh0dHBzOi8vb3BlbmFpLmNvbS9pbmRleC9pbnRyb2R1Y2luZy1ncHQtNS0yLyAoY2FjaGVkIGlucHV0IDkwJSDtlaDsnbgg66qF7IucKVxuICBcImdwdC01LjJcIjogeyBpbnB1dFRva2VuczogMS43NSwgb3V0cHV0VG9rZW5zOiAxNCwgY2FjaGVkSW5wdXRUb2tlbnM6IDAuMTc1IH0sXG59O1xuXG4vLyDilIDilIAgQW50aHJvcGljIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG5mdW5jdGlvbiBhbnRocm9waWNDb3N0cyhcbiAgaW5wdXRUb2tlbnM6IG51bWJlcixcbiAgb3V0cHV0VG9rZW5zOiBudW1iZXIsXG4gIG92ZXJyaWRlczogUGljazxQYXJ0aWFsPE1vZGVsQ29zdHM+LCBcImNhY2hlZElucHV0VG9rZW5zXCIgfCBcImxvbmdDb250ZXh0XCI+ID0ge30sXG4pOiBNb2RlbENvc3RzIHtcbiAgcmV0dXJuIHtcbiAgICBpbnB1dFRva2VucyxcbiAgICBvdXRwdXRUb2tlbnMsXG4gICAgLy8g7ZGc7KSAIGNhY2hlIHJlYWQg64qUIGJhc2UgaW5wdXQg7J2YIDAuMXguIEZhYmxlIDUuMSDsspjrn7wg6rO17IudIO2KueuhgCDri6jqsIDqsIAg7J6I7Jy866m0IG92ZXJyaWRlIO2VnOuLpC5cbiAgICBjYWNoZWRJbnB1dFRva2Vuczogb3ZlcnJpZGVzLmNhY2hlZElucHV0VG9rZW5zID8/IGlucHV0VG9rZW5zIC8gMTAsXG4gICAgLy8gQ2xhdWRlIENvZGUgc3Vic2NyaXB0aW9uIE9BdXRoIOuKlCAxaCBUVEwg7J2EIOyekOuPmSDshKDtg53tlZzri6QuIOq1rOuyhOyghOyymOufvCDsnZHri7Xsl5BcbiAgICAvLyBUVEwgYnJlYWtkb3duIOydtCDsl4bsnYQg65WM66eMIOydtCAxaCDri6jqsIDrpbwgZmFsbGJhY2sg7Jy866GcIOyCrOyaqe2VnOuLpC5cbiAgICBjYWNoZUNyZWF0aW9uSW5wdXRUb2tlbnM6IGlucHV0VG9rZW5zICogMixcbiAgICBjYWNoZUNyZWF0aW9uSW5wdXRUb2tlbnM1bTogaW5wdXRUb2tlbnMgKiAxLjI1LFxuICAgIGNhY2hlQ3JlYXRpb25JbnB1dFRva2VuczFoOiBpbnB1dFRva2VucyAqIDIsXG4gICAgLy8gSGFpa3UgNS41IOyymOufvCDtlITroaztlITtirgg6ri47J20IO2LsOyWtOqwgCDsnojripQg66qo642466eMIGxvbmctY29udGV4dCDrsLDsnKjsnYQg6rCA7KeE64ukLlxuICAgIC4uLihvdmVycmlkZXMubG9uZ0NvbnRleHQgPyB7IGxvbmdDb250ZXh0OiBvdmVycmlkZXMubG9uZ0NvbnRleHQgfSA6IHt9KSxcbiAgfTtcbn1cblxuLy8g6rCA6rKpIOy2nOyymDogaHR0cHM6Ly9wbGF0Zm9ybS5jbGF1ZGUuY29tL2RvY3MvZW4vYWJvdXQtY2xhdWRlL3ByaWNpbmcgKDIwMjYtMTAtMDgg7ZmV7J24LiAyMDI2LTEwLTA3IOyXkCBTb25uZXQgNS41XG4vLyBjYWNoZSByZWFkIOqwgCAkMC4yMOKGkiQwLjEwKDAuMDV4KeycvOuhnCDsnbjtlZjrkJDqs6AsIOq3uCDsmbgg6riw7KG0IOuqqOuNuCDri6jqsIDripQg67OA64+ZIOyXhuydjClcbmNvbnN0IEFOVEhST1BJQ19DT1NUUzogUmVjb3JkPHN0cmluZywgTW9kZWxDb3N0cz4gPSB7XG4gIC8vIEZhYmxlIDUuMSAoMjAyNi0wOS0wMSDstpzsi5wpOiBpbnB1dC9vdXRwdXQg7J2AIEZhYmxlIDUg7JmAIOqwmeqzoCBjYWNoZSByZWFkIOunjCAwLjAyNXgoJDAuMjUpIO2KueuhgC5cbiAgLy8gQHNlZSBodHRwczovL3BsYXRmb3JtLmNsYXVkZS5jb20vZG9jcy9lbi9tb2RlbHMvZmFibGUtNS0xL292ZXJ2aWV3XG4gIFwiY2xhdWRlLWZhYmxlLTUtMVwiOiBhbnRocm9waWNDb3N0cygxMCwgNTAsIHsgY2FjaGVkSW5wdXRUb2tlbnM6IDAuMjUgfSksXG4gIFwiY2xhdWRlLWZhYmxlLTVcIjogYW50aHJvcGljQ29zdHMoMTAsIDUwKSxcbiAgc29ubmV0OiBhbnRocm9waWNDb3N0cygzLCAxNSksXG4gIFwiY2xhdWRlLTMtNS1oYWlrdVwiOiBhbnRocm9waWNDb3N0cygwLjgsIDQpLFxuICBcImNsYXVkZS1oYWlrdS00LTVcIjogYW50aHJvcGljQ29zdHMoMSwgNSksXG4gIFwiY2xhdWRlLTMtNS1zb25uZXRcIjogYW50aHJvcGljQ29zdHMoMywgMTUpLFxuICBcImNsYXVkZS0zLTctc29ubmV0XCI6IGFudGhyb3BpY0Nvc3RzKDMsIDE1KSxcbiAgXCJjbGF1ZGUtc29ubmV0LTRcIjogYW50aHJvcGljQ29zdHMoMywgMTUpLFxuICBcImNsYXVkZS1zb25uZXQtNC01XCI6IGFudGhyb3BpY0Nvc3RzKDMsIDE1KSxcbiAgXCJjbGF1ZGUtc29ubmV0LTQtNlwiOiBhbnRocm9waWNDb3N0cygzLCAxNSksXG4gIFwiY2xhdWRlLXNvbm5ldC00LTdcIjogYW50aHJvcGljQ29zdHMoMywgMTUpLFxuICBcImNsYXVkZS1vcHVzLTRcIjogYW50aHJvcGljQ29zdHMoMTUsIDc1KSxcbiAgXCJjbGF1ZGUtb3B1cy00LTFcIjogYW50aHJvcGljQ29zdHMoMTUsIDc1KSxcbiAgXCJjbGF1ZGUtb3B1cy00LTVcIjogYW50aHJvcGljQ29zdHMoNSwgMjUpLFxuICBcImNsYXVkZS1vcHVzLTQtNlwiOiBhbnRocm9waWNDb3N0cyg1LCAyNSksXG4gIFwiY2xhdWRlLW9wdXMtNC03XCI6IGFudGhyb3BpY0Nvc3RzKDUsIDI1KSxcbiAgXCJjbGF1ZGUtb3B1cy00LThcIjogYW50aHJvcGljQ29zdHMoNSwgMjUpLFxuICBcImNsYXVkZS1vcHVzLTVcIjogYW50aHJvcGljQ29zdHMoNSwgMjUpLFxuICAvLyBPcHVzIDUuNSAoMjAyNi0wOS0yMiDstpzsi5wpOiAkNC8kMjAuIGNhY2hlIHJlYWQg64qUIDAuMDV4KCQwLjIwKSDtirnroYAsIGNhY2hlIHdyaXRlIOuKlCDtkZzspIAg67Cw7JyoKCQ1LyQ4KS5cbiAgLy8gQHNlZSBodHRwczovL3BsYXRmb3JtLmNsYXVkZS5jb20vZG9jcy9lbi9tb2RlbHMvb3B1cy01LTUvb3ZlcnZpZXdcbiAgXCJjbGF1ZGUtb3B1cy01LTVcIjogYW50aHJvcGljQ29zdHMoNCwgMjAsIHsgY2FjaGVkSW5wdXRUb2tlbnM6IDAuMiB9KSxcbiAgLy8gU29ubmV0IDUg7J2YIGludHJvZHVjdG9yeSAkMi8kMTAg7J20IOygleyLnSDri6jqsIDroZwg7ZmV7KCV65CQ64ukLiAyMDI2LTA5LTAxIOyXkCDsmIjsoJXrkJDrjZggJDMvJDE1IOyduOyDgeydgFxuICAvLyDst6jshozrkJDsnLzrr4DroZwg64Kg7KecIOu2hOq4sCDsl4bsnbQg6rOg7KCVIOuLqOqwgOuhnCDqs4TsgrDtlZzri6QuXG4gIFwiY2xhdWRlLXNvbm5ldC01XCI6IGFudGhyb3BpY0Nvc3RzKDIsIDEwKSxcbiAgLy8gU29ubmV0IDUuNSAoMjAyNi0wOS0yOCDstpzsi5wpOiBTb25uZXQgNSDsmYAg6rCZ7J2AICQyLyQxMC4gY2FjaGUgcmVhZCDripQg7Lac7IucIOyLnCDtkZzspIAgMC4xeCgkMC4yMCnsmIDri6TqsIBcbiAgLy8gMjAyNi0xMC0wNyBIYWlrdSA1LjUg7Lac7Iuc7JmAIO2VqOq7mCBPcHVzIDUuNSDsmYAg6rCZ7J2AIDAuMDV4KCQwLjEwKeuhnCDsnbjtlZjrkJDri6QoQVBJIOumtOumrOyKpCDrhbjtirgpLiDruYTsmqnsnYAg7JqU7LKtIOyLnOygkFxuICAvLyDri6jqsIDroZwg6riw66Gd65CY66+A66GcIOuCoOynnCDrtoTquLAg7JeG7J20IO2YhO2WiSDri6jqsIDrp4wg65GU64ukLiBjYWNoZSB3cml0ZSDripQg7ZGc7KSAIOuwsOycqCgkMi41MC8kNCkuXG4gIC8vIEBzZWUgaHR0cHM6Ly9wbGF0Zm9ybS5jbGF1ZGUuY29tL2RvY3MvZW4vcmVsZWFzZS1ub3Rlcy9vdmVydmlldyAoMjAyNi0xMC0wNylcbiAgXCJjbGF1ZGUtc29ubmV0LTUtNVwiOiBhbnRocm9waWNDb3N0cygyLCAxMCwgeyBjYWNoZWRJbnB1dFRva2VuczogMC4xIH0pLFxuICAvLyBIYWlrdSA1LjUgKDIwMjYtMTAtMDcg7Lac7IucKTog7ZSE66Gs7ZSE7Yq4IOq4uOydtCDti7DslrQg64uo6rCALiAxMDBLIOydtO2VmCAkMC4xMC8kMC41MCwgY2FjaGUgcmVhZCAwLjF4KCQwLjAxKSxcbiAgLy8gY2FjaGUgd3JpdGUgNW0gJDAuMTI1IC8gMWggJDAuMjAuIOyeheugpeydtCAxMDBLIOulvCDrhJjsnLzrqbQgaW5wdXQvY2FjaGUgcmVhZC9jYWNoZSB3cml0ZS9vdXRwdXQg66qo65GQIDV4XG4gIC8vICgkMC41MC8kMC4wNS8kMC42MjXCtyQxLyQyLjUwKeqwgCDsmpTssq0g7KCE7LK07JeQIOyggeyaqeuQnOuLpC4gMU0g7Luo7YWN7Iqk7Yq4IOuqqOuNuCDspJEg7Jyg7J287ZWY6rKMIOq4uOydtOuzhCDri6jqsIDrpbwg7JO064ukLlxuICAvLyBAc2VlIGh0dHBzOi8vcGxhdGZvcm0uY2xhdWRlLmNvbS9kb2NzL2VuL21vZGVscy9oYWlrdS01LTUvb3ZlcnZpZXdcbiAgXCJjbGF1ZGUtaGFpa3UtNS01XCI6IGFudGhyb3BpY0Nvc3RzKDAuMSwgMC41LCB7XG4gICAgbG9uZ0NvbnRleHQ6IHtcbiAgICAgIHRocmVzaG9sZDogMTAwXzAwMCxcbiAgICAgIGlucHV0TXVsdGlwbGllcjogNSxcbiAgICAgIGNhY2hlZElucHV0TXVsdGlwbGllcjogNSxcbiAgICAgIG91dHB1dE11bHRpcGxpZXI6IDUsXG4gICAgfSxcbiAgfSksXG59O1xuXG4vLyBncHQtNS4zLWNvZGV4LXNwYXJrIOuKlCByZXNlYXJjaCBwcmV2aWV3IOuhnCDqs7Xsi50gdG9rZW4g64uo6rCA6rCAIOyVhOyngSBmaW5hbCDsnbQg7JWE64uI64ukLlxuLy8g7KeA7JuQIO2DgOyeheydgCDsnKDsp4DtlZjrkJgsIOqzteyLnSDri6jqsIDqsIAg6rO16rCc65CgIOuVjOq5jOyngCDslYTrnpggZ2VuZXJpYyBlc3RpbWF0ZSDroZwg6rOE7IKw7ZWc64ukLlxuLy8gQHNlZSBodHRwczovL2hlbHAub3BlbmFpLmNvbS9lbi9hcnRpY2xlcy8yMDAwMTEwNi1jb2RleC1yYXRlLWNhcmRcbmNvbnN0IERFRkFVTFRfQ09TVFM6IE1vZGVsQ29zdHMgPSB7IGlucHV0VG9rZW5zOiAzLCBvdXRwdXRUb2tlbnM6IDE1LCBjYWNoZWRJbnB1dFRva2VuczogMC4zIH07XG5cbi8qKiBDb2RleCDrsLHsl5Trk5zqsIAg7J20IOuqqOuNuOyXkCDtl4jsmqntlZjripQg7LWc64yAIGVmZm9ydC4g7Lm07YOI66Gc6re47JeQIOyXhuuKlCDrqqjrjbjsnYAgeGhpZ2gg6rmM7KeA64ukLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG9wZW5haU1vZGVsTWF4RWZmb3J0KG1vZGVsOiBzdHJpbmcpOiBPcGVuQUlFZmZvcnQge1xuICByZXR1cm4gT1BFTkFJX0NPU1RTW21vZGVsXT8ubWF4RWZmb3J0ID8/IFwieGhpZ2hcIjtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldE1vZGVsQ29zdHMobW9kZWw6IHN0cmluZyk6IE1vZGVsQ29zdHMge1xuICBjb25zdCBub3JtYWxpemVkTW9kZWwgPSAobW9kZWwuc3BsaXQoXCIvXCIpLnBvcCgpID8/IG1vZGVsKS5yZXBsYWNlKC9cXFsxbVxcXSQvaSwgXCJcIik7XG4gIHJldHVybiBPUEVOQUlfQ09TVFNbbm9ybWFsaXplZE1vZGVsXSA/PyBBTlRIUk9QSUNfQ09TVFNbbm9ybWFsaXplZE1vZGVsXSA/PyBERUZBVUxUX0NPU1RTO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY2FsY3VsYXRlQ29zdFVzZChcbiAgbW9kZWw6IHN0cmluZyxcbiAgdXNhZ2U6IHtcbiAgICBpbnB1dFRva2VuczogbnVtYmVyO1xuICAgIG91dHB1dFRva2VuczogbnVtYmVyO1xuICAgIGNhY2hlZElucHV0VG9rZW5zPzogbnVtYmVyO1xuICAgIGNhY2hlQ3JlYXRpb25JbnB1dFRva2Vucz86IG51bWJlcjtcbiAgICBjYWNoZUNyZWF0aW9uSW5wdXRUb2tlbnM1bT86IG51bWJlcjtcbiAgICBjYWNoZUNyZWF0aW9uSW5wdXRUb2tlbnMxaD86IG51bWJlcjtcbiAgfSxcbik6IG51bWJlciB7XG4gIGNvbnN0IGNvc3RzID0gZ2V0TW9kZWxDb3N0cyhtb2RlbCk7XG4gIGNvbnN0IGNhY2hlZElucHV0ID0gdXNhZ2UuY2FjaGVkSW5wdXRUb2tlbnMgPz8gMDtcbiAgY29uc3QgY2FjaGVDcmVhdGlvbklucHV0NW0gPSBNYXRoLm1heCh1c2FnZS5jYWNoZUNyZWF0aW9uSW5wdXRUb2tlbnM1bSA/PyAwLCAwKTtcbiAgY29uc3QgY2FjaGVDcmVhdGlvbklucHV0MWggPSBNYXRoLm1heCh1c2FnZS5jYWNoZUNyZWF0aW9uSW5wdXRUb2tlbnMxaCA/PyAwLCAwKTtcbiAgY29uc3QgY2FjaGVDcmVhdGlvbklucHV0ID0gTWF0aC5tYXgoXG4gICAgdXNhZ2UuY2FjaGVDcmVhdGlvbklucHV0VG9rZW5zID8/IDAsXG4gICAgY2FjaGVDcmVhdGlvbklucHV0NW0gKyBjYWNoZUNyZWF0aW9uSW5wdXQxaCxcbiAgKTtcbiAgY29uc3QgY2xhc3NpZmllZENhY2hlQ3JlYXRpb25JbnB1dDVtID0gTWF0aC5taW4oY2FjaGVDcmVhdGlvbklucHV0NW0sIGNhY2hlQ3JlYXRpb25JbnB1dCk7XG4gIGNvbnN0IGNsYXNzaWZpZWRDYWNoZUNyZWF0aW9uSW5wdXQxaCA9IE1hdGgubWluKFxuICAgIGNhY2hlQ3JlYXRpb25JbnB1dDFoLFxuICAgIGNhY2hlQ3JlYXRpb25JbnB1dCAtIGNsYXNzaWZpZWRDYWNoZUNyZWF0aW9uSW5wdXQ1bSxcbiAgKTtcbiAgY29uc3QgdW5jbGFzc2lmaWVkQ2FjaGVDcmVhdGlvbklucHV0ID1cbiAgICBjYWNoZUNyZWF0aW9uSW5wdXQgLSBjbGFzc2lmaWVkQ2FjaGVDcmVhdGlvbklucHV0NW0gLSBjbGFzc2lmaWVkQ2FjaGVDcmVhdGlvbklucHV0MWg7XG4gIGNvbnN0IG5vbkNhY2hlZElucHV0ID0gTWF0aC5tYXgodXNhZ2UuaW5wdXRUb2tlbnMgLSBjYWNoZWRJbnB1dCAtIGNhY2hlQ3JlYXRpb25JbnB1dCwgMCk7XG5cbiAgLy8gbG9uZy1jb250ZXh0IO2VoOymnTog7KCE7LK0IOyeheugpShpbnB1dF90b2tlbnMsIGNhY2hlIO2PrO2VqCnsnbQgdGhyZXNob2xkIOy0iOqzvCDsi5wg7JqU7LKtIOyghOyytOyXkCDrsLDsnKgg7KCB7JqpXG4gIGNvbnN0IGxjID0gY29zdHMubG9uZ0NvbnRleHQ7XG4gIGNvbnN0IGlzTG9uZ0NvbnRleHQgPSBsYyAhPT0gdW5kZWZpbmVkICYmIHVzYWdlLmlucHV0VG9rZW5zID4gbGMudGhyZXNob2xkO1xuICBjb25zdCBpbnB1dFJhdGUgPSBjb3N0cy5pbnB1dFRva2VucyAqIChpc0xvbmdDb250ZXh0ID8gbGMuaW5wdXRNdWx0aXBsaWVyIDogMSk7XG4gIGNvbnN0IGNhY2hlZFJhdGUgPSBjb3N0cy5jYWNoZWRJbnB1dFRva2VucyAqIChpc0xvbmdDb250ZXh0ID8gbGMuY2FjaGVkSW5wdXRNdWx0aXBsaWVyIDogMSk7XG4gIGNvbnN0IGNhY2hlQ3JlYXRpb25GYWxsYmFja1JhdGUgPVxuICAgIChjb3N0cy5jYWNoZUNyZWF0aW9uSW5wdXRUb2tlbnMgPz8gY29zdHMuaW5wdXRUb2tlbnMpICpcbiAgICAoaXNMb25nQ29udGV4dCA/IGxjLmlucHV0TXVsdGlwbGllciA6IDEpO1xuICBjb25zdCBjYWNoZUNyZWF0aW9uNW1SYXRlID1cbiAgICAoY29zdHMuY2FjaGVDcmVhdGlvbklucHV0VG9rZW5zNW0gPz8gY29zdHMuY2FjaGVDcmVhdGlvbklucHV0VG9rZW5zID8/IGNvc3RzLmlucHV0VG9rZW5zKSAqXG4gICAgKGlzTG9uZ0NvbnRleHQgPyBsYy5pbnB1dE11bHRpcGxpZXIgOiAxKTtcbiAgY29uc3QgY2FjaGVDcmVhdGlvbjFoUmF0ZSA9XG4gICAgKGNvc3RzLmNhY2hlQ3JlYXRpb25JbnB1dFRva2VuczFoID8/IGNvc3RzLmNhY2hlQ3JlYXRpb25JbnB1dFRva2VucyA/PyBjb3N0cy5pbnB1dFRva2VucykgKlxuICAgIChpc0xvbmdDb250ZXh0ID8gbGMuaW5wdXRNdWx0aXBsaWVyIDogMSk7XG4gIGNvbnN0IG91dHB1dFJhdGUgPSBjb3N0cy5vdXRwdXRUb2tlbnMgKiAoaXNMb25nQ29udGV4dCA/IGxjLm91dHB1dE11bHRpcGxpZXIgOiAxKTtcblxuICByZXR1cm4gKFxuICAgIChub25DYWNoZWRJbnB1dCAvIDFfMDAwXzAwMCkgKiBpbnB1dFJhdGUgK1xuICAgICh1c2FnZS5vdXRwdXRUb2tlbnMgLyAxXzAwMF8wMDApICogb3V0cHV0UmF0ZSArXG4gICAgKGNhY2hlZElucHV0IC8gMV8wMDBfMDAwKSAqIGNhY2hlZFJhdGUgK1xuICAgICh1bmNsYXNzaWZpZWRDYWNoZUNyZWF0aW9uSW5wdXQgLyAxXzAwMF8wMDApICogY2FjaGVDcmVhdGlvbkZhbGxiYWNrUmF0ZSArXG4gICAgKGNsYXNzaWZpZWRDYWNoZUNyZWF0aW9uSW5wdXQ1bSAvIDFfMDAwXzAwMCkgKiBjYWNoZUNyZWF0aW9uNW1SYXRlICtcbiAgICAoY2xhc3NpZmllZENhY2hlQ3JlYXRpb25JbnB1dDFoIC8gMV8wMDBfMDAwKSAqIGNhY2hlQ3JlYXRpb24xaFJhdGVcbiAgKTtcbn1cbiJdLCJtYXBwaW5ncyI6IjtBQTBDQSxNQUFNLG9CQUE0RDtDQUNoRSxXQUFXO0NBQ1gsaUJBQWlCO0NBQ2pCLHVCQUF1QjtDQUN2QixrQkFBa0I7QUFDcEI7QUFPQSxNQUFNLGVBQWdEO0NBS3BELGVBQWU7RUFDYixXQUFXO0VBQ1gsYUFBYTtFQUNiLGNBQWM7RUFDZCxtQkFBbUI7RUFDbkIsMEJBQTBCO0VBQzFCLGFBQWE7Q0FDZjtDQUtBLGVBQWU7RUFDYixXQUFXO0VBQ1gsYUFBYTtFQUNiLGNBQWM7RUFDZCxtQkFBbUI7RUFDbkIsMEJBQTBCO0VBQzFCLGFBQWE7Q0FDZjtDQUtBLGFBQWE7RUFDWCxXQUFXO0VBQ1gsYUFBYTtFQUNiLGNBQWM7RUFDZCxtQkFBbUI7RUFDbkIsMEJBQTBCO0VBQzFCLGFBQWE7Q0FDZjtDQUNBLGNBQWM7RUFDWixXQUFXO0VBQ1gsYUFBYTtFQUNiLGNBQWM7RUFDZCxtQkFBbUI7RUFDbkIsMEJBQTBCO0VBQzFCLGFBQWE7Q0FDZjtDQVFBLGVBQWU7RUFDYixXQUFXO0VBQ1gsYUFBYTtFQUNiLGNBQWM7RUFDZCxtQkFBbUI7RUFDbkIsMEJBQTBCO0VBQzFCLGFBQWE7Q0FDZjtDQUNBLGlCQUFpQjtFQUNmLFdBQVc7RUFDWCxhQUFhO0VBQ2IsY0FBYztFQUNkLG1CQUFtQjtFQUNuQiwwQkFBMEI7RUFDMUIsYUFBYTtDQUNmO0NBQ0EsZ0JBQWdCO0VBQ2QsV0FBVztFQUNYLGFBQWE7RUFDYixjQUFjO0VBQ2QsbUJBQW1CO0VBQ25CLDBCQUEwQjtFQUMxQixhQUFhO0NBQ2Y7Q0FFQSxXQUFXO0VBQ1QsYUFBYTtFQUNiLGNBQWM7RUFDZCxtQkFBbUI7RUFDbkIsYUFBYTtDQUNm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
@@ -14,8 +14,6 @@ describe("decideConvRouting", () => {
14
14
  it("일반 cold 첫 turn 은 기존 prompt 를 실행 input 으로 유지한다", () => {
15
15
  const decision = decideConvRouting(input({ prompt: "first turn" }));
16
16
 
17
- expect(decision.reuse).toBeUndefined();
18
- expect(decision.reuseInput).toBeUndefined();
19
17
  expect(decision.coldInput).toEqual([{ type: "text", text: "first turn", text_elements: [] }]);
20
18
  });
21
19
 
@@ -46,7 +44,6 @@ describe("decideConvRouting", () => {
46
44
  }),
47
45
  );
48
46
 
49
- expect(decision.reuse).toBeUndefined();
50
47
  expect(decision.coldHistory).toHaveLength(2);
51
48
  expect(decision.coldInput).toEqual([
52
49
  {
@@ -88,32 +85,6 @@ describe("decideConvRouting", () => {
88
85
  ]);
89
86
  });
90
87
 
91
- it("reuse 가능한 tool result follow-up 은 reuseInput 과 coldInput 이 같은 continuation 을 쓴다", () => {
92
- const decision = decideConvRouting(
93
- input({
94
- prompt: "",
95
- system: "same",
96
- runContext: {
97
- threadCoord: {
98
- workerId: 1,
99
- threadId: "S1",
100
- epoch: 0,
101
- systemHash: systemHash("same"),
102
- },
103
- },
104
- toolResults: [{ toolCallId: "call_1", output: "ok" }],
105
- }),
106
- );
107
-
108
- expect(decision.reuse).toEqual({ workerId: 1, threadId: "S1", epoch: 0 });
109
- expect(decision.reuseInput).toEqual(decision.coldInput);
110
- expect(decision.coldInput[0]).toMatchObject({
111
- type: "text",
112
- text: expect.stringContaining("Tool result for call call_1"),
113
- });
114
- expect(decision.coldInput[0]).not.toMatchObject({ type: "text", text: "" });
115
- });
116
-
117
88
  it("direct OpenAI는 epoch=-1 좌표를 opaque cache affinity로 해석하고 전체 history를 유지한다", () => {
118
89
  const cacheAffinityKey = "a".repeat(64);
119
90
  const model = "openai/gpt-5.5";
@@ -136,8 +107,6 @@ describe("decideConvRouting", () => {
136
107
  { directOpenAI: true, modelNamespace: model },
137
108
  );
138
109
 
139
- expect(decision.reuse).toBeUndefined();
140
- expect(decision.reuseInput).toBeUndefined();
141
110
  expect(decision.coldHistory).toEqual([{ role: "user", content: "first" }]);
142
111
  expect(decision.coldInput).toEqual([{ type: "text", text: "next", text_elements: [] }]);
143
112
  expect(decision.promptCacheKey).toBe(cacheAffinityKey);
@@ -164,7 +133,6 @@ describe("decideConvRouting", () => {
164
133
 
165
134
  expect(decision.promptCacheKey).toBe(cacheAffinityKey);
166
135
  expect(decision.preferredTokenId).toBeUndefined();
167
- expect(decision.reuse).toBeUndefined();
168
136
  });
169
137
 
170
138
  it("system hash separates model namespaces", () => {
@@ -1,12 +1,9 @@
1
1
  /**
2
2
  * conv-routing — 대화 연속성(cache affinity) 좌표 검증/구성.
3
3
  *
4
- * 목표: thread(=conversation_id=prompt_cache_key)를 재사용해 OpenAI prompt caching 적중.
5
- * - 후속 turn: 기존 thread 에 delta(마지막 user / tool 결과)만 보냄 (history inject 없음).
6
- * - 첫 turn / 검증 실패: 새 thread + history inject (폴백, 정확성 보존).
7
- *
8
- * 식별: 서버 발급 불투명 thread 좌표(QgridThreadCoord)를 클라가 그대로 회송.
9
- * 검증: systemHash(다른 대화 오접속 차단) + (dispatcher의) epoch/worker 생존.
4
+ * 모든 turn은 현재 input과 전체 history를 전달한다.
5
+ * OpenAI의 epoch=-1 좌표는 system/model hash와 opaque affinity를 검증한 뒤
6
+ * token 선택과 prompt-cache 힌트로만 사용한다.
10
7
  */
11
8
  import { createHash } from "node:crypto";
12
9
 
@@ -32,13 +29,9 @@ function toolResultsToText(toolResults: QgridToolResultInput[]): string {
32
29
  }
33
30
 
34
31
  export interface ConvDecision {
35
- // dispatcher 로 넘길 reuse 좌표 (검증 통과 시에만). dispatcher 가 epoch/worker 생존 재검증 후 폴백 가능.
36
- reuse?: ReuseThreadCoord;
37
- // 재사용 성공 시 turn/start 에 보낼 input — delta(마지막 user/tool 결과)만. reuse 가 있을 때만 설정.
38
- reuseInput?: Array<UserInput>;
39
- // 첫 turn / 재사용 폴백 시 보낼 input — 전체 prompt. 항상 설정(폴백 안전망).
32
+ // 매 turn의 현재 user/tool input.
40
33
  coldInput: Array<UserInput>;
41
- // 새 thread 일 때 inject 할 전체 history. 재사용 성공 시엔 dispatcher 가 안 쓴다(thread 가 이미 누적).
34
+ // 매 turn에 다시 전달할 전체 history.
42
35
  coldHistory?: Array<JsonValue>;
43
36
  // 이 요청 시점의 system 해시 (응답에서 thread 좌표 발급 시 사용).
44
37
  systemHash: string;
@@ -52,10 +45,7 @@ export interface ConvRoutingOptions {
52
45
  modelNamespace?: string;
53
46
  }
54
47
 
55
- // thread 좌표 + 들어온 요청으로 "재사용 가능한가"를 판정하고, reuse/cold 양쪽 payload 를 구성한다.
56
- // dispatcher 단의 epoch/worker 생존 검증은 여기서 못 하므로(상태 없음) reuse 좌표 + 두 payload 를
57
- // 모두 넘기고, dispatcher 의 acquireReuseWorker 결과에 따라 reuse(delta) 또는 cold(전체) 를 고른다.
58
- // 양쪽을 다 들고 가야 reuse 가 실패로 폴백돼도 전체 history 로 문맥을 복구할 수 있다.
48
+ // 입력과 전체 history를 구성하고, 검증된 OpenAI cache affinity만 부가한다.
59
49
  export function decideConvRouting(
60
50
  input: QueryInput,
61
51
  options: ConvRoutingOptions = {},
@@ -78,21 +68,12 @@ export function decideConvRouting(
78
68
  coord.systemHash === sysHash &&
79
69
  input.cacheAffinityKey !== undefined &&
80
70
  coord.threadId === input.cacheAffinityKey;
81
- const legacyReuseEligible =
82
- options.directOpenAI !== true && coord !== undefined && coord.systemHash === sysHash;
83
71
  // affinity 를 요청하지 않은 one-shot 요청에 임의 키를 붙이면 transport 가 그 소켓을
84
72
  // affinity 소켓으로 오인해 재사용되지 않을 연결을 계속 붙들어 둔다 → 키를 비워 둔다.
85
73
  const cacheKey = options.directOpenAI ? input.cacheAffinityKey : undefined;
86
74
 
87
75
  return {
88
- reuse:
89
- legacyReuseEligible && coord
90
- ? { workerId: coord.workerId, threadId: coord.threadId, epoch: coord.epoch }
91
- : undefined,
92
- // 재사용 turn 은 delta(마지막 user/tool 결과)만 — thread 가 이미 이전 turn 들을 누적.
93
- reuseInput: legacyReuseEligible ? buildDeltaInput(input) : undefined,
94
- // 첫 turn / 폴백: 전체 prompt + history inject. tool 결과 follow-up 이 cold 로 떨어져도
95
- // 실행 user 줄에는 "이 결과로 계속 답하라"는 continuation 이 들어가야 한다.
76
+ // tool follow-up도 실행 user 줄에 결과를 사용해 계속 답하라는 안내를 담는다.
96
77
  coldInput: buildDeltaInput(input),
97
78
  coldHistory: history,
98
79
  systemHash: sysHash,
@@ -8,6 +8,7 @@ import {
8
8
  import { systemHash } from "./conv-routing";
9
9
  import { buildStrictOutputSchema, QgridDispatcherClass } from "./qgrid.dispatcher";
10
10
  import { type QueryOutput } from "./qgrid.types";
11
+ import { type TokenSubsetA } from "../sonamu.generated";
11
12
 
12
13
  function providerResult(overrides: Partial<GenerateResult> = {}): GenerateResult {
13
14
  return {
@@ -33,6 +34,40 @@ function deeplyNestedOutputSchema(depth: number): string {
33
34
  }
34
35
 
35
36
  describe("QgridDispatcherClass", () => {
37
+ it("counts completed query and stream generations separately for providers sharing a token name", async () => {
38
+ const dispatcher = new QgridDispatcherClass();
39
+ dispatcher.replaceCache(
40
+ ["openai", "anthropic"].map((provider, index) => ({
41
+ id: index + 1,
42
+ provider,
43
+ name: "shared",
44
+ credentials: { accessToken: "test-token" },
45
+ }) as TokenSubsetA),
46
+ );
47
+
48
+ const generate = vi.fn(async () => providerResult({ tokenName: "shared" }));
49
+ const generateStream = vi.fn(async (_request: GenerateRequest, cb: GenerateStreamCallbacks) => {
50
+ cb.onComplete(providerResult({ tokenName: "shared" }));
51
+ });
52
+ dispatcher.openaiDispatcher = { generate, generateStream } as never;
53
+ dispatcher.anthropicDispatcher = { generate, generateStream } as never;
54
+ const callbacks = { onDelta: vi.fn(), onComplete: vi.fn(), onError: vi.fn() };
55
+
56
+ await dispatcher.query({ prompt: "hi", model: "openai/gpt-5.5" });
57
+ expect(dispatcher.getStats().map((row) => row.requests)).toEqual([1, 0]);
58
+ await dispatcher.queryStream({ prompt: "hi", model: "openai/gpt-5.5" }, callbacks);
59
+ await dispatcher.query({ prompt: "hi", model: "anthropic/claude-sonnet-4-6" });
60
+ await dispatcher.queryStream({ prompt: "hi", model: "anthropic/claude-sonnet-4-6" }, callbacks);
61
+ expect(dispatcher.getStats().map((row) => row.requests)).toEqual([2, 2]);
62
+
63
+ generate.mockRejectedValueOnce(new Error("provider failed"));
64
+ await expect(dispatcher.query({ prompt: "hi", model: "openai/gpt-5.5" })).rejects.toThrow("provider failed");
65
+ generateStream.mockImplementationOnce(async (_request, cb) => cb.onError(new Error("stream failed")));
66
+ await dispatcher.queryStream({ prompt: "hi", model: "anthropic/claude-sonnet-4-6" }, callbacks);
67
+ expect(callbacks.onError).toHaveBeenCalledOnce();
68
+ expect(dispatcher.getStats().map((row) => row.requests)).toEqual([2, 2]);
69
+ });
70
+
36
71
  const toolsAndSchema = {
37
72
  tools: [
38
73
  {
@@ -115,45 +150,6 @@ describe("QgridDispatcherClass", () => {
115
150
  expect(generate).not.toHaveBeenCalled();
116
151
  });
117
152
 
118
- it("Anthropic queryStream 은 abortSignal 을 provider request 로 전달한다", async () => {
119
- const dispatcher = new QgridDispatcherClass();
120
- const generateStream = vi.fn(async (_req: GenerateRequest, _cb: GenerateStreamCallbacks) => {});
121
- dispatcher.anthropicDispatcher = { generateStream } as never;
122
- const abortSignal = new AbortController().signal;
123
-
124
- await dispatcher.queryStream(
125
- { prompt: "hi", model: "anthropic/claude-sonnet-4-6", timeout: 360_000 },
126
- {
127
- onDelta: vi.fn(),
128
- onComplete: vi.fn(),
129
- onError: vi.fn(),
130
- },
131
- abortSignal,
132
- );
133
-
134
- expect(generateStream.mock.calls[0]![0].abortSignal).toBe(abortSignal);
135
- expect(generateStream.mock.calls[0]![0].timeoutMs).toBe(360_000);
136
- });
137
-
138
- it("Anthropic query 는 timeoutMs와 abortSignal을 provider request로 전달한다", async () => {
139
- const dispatcher = new QgridDispatcherClass();
140
- const generate = vi.fn(async (_req: GenerateRequest) =>
141
- providerResult({ model: "claude-opus-5" }),
142
- );
143
- dispatcher.anthropicDispatcher = { generate } as never;
144
- const abortSignal = new AbortController().signal;
145
-
146
- await dispatcher.query(
147
- { prompt: "hi", model: "anthropic/claude-opus-5", timeout: 360_000 },
148
- abortSignal,
149
- );
150
-
151
- expect(generate.mock.calls[0]![0]).toMatchObject({
152
- timeoutMs: 360_000,
153
- abortSignal,
154
- });
155
- });
156
-
157
153
  it("Anthropic queryStream provider error 는 상위 onError 로 전달한다", async () => {
158
154
  const dispatcher = new QgridDispatcherClass();
159
155
  const serverError = new Error(
@@ -246,72 +242,50 @@ describe("QgridDispatcherClass", () => {
246
242
  });
247
243
  });
248
244
 
249
- it("Anthropic query 는 reuse/reuseInput 을 provider 로 전달하지 않는다", async () => {
245
+ it("Anthropic query 는 실행 옵션을 전달하고 legacy reuse 필드는 제외한다", async () => {
250
246
  const dispatcher = new QgridDispatcherClass();
251
247
  const generate = vi.fn(async (_req: GenerateRequest) =>
252
248
  providerResult({ model: "claude-sonnet-4-6" }),
253
249
  );
254
250
  dispatcher.anthropicDispatcher = { generate } as never;
251
+ const abortSignal = new AbortController().signal;
255
252
 
256
- await dispatcher.query({
257
- prompt: "next",
258
- model: "anthropic/claude-sonnet-4-6",
259
- system: "same-system",
260
- runContext: {
261
- threadCoord: {
262
- workerId: 1,
263
- threadId: "thread-1",
264
- epoch: 0,
265
- systemHash: "800ddd9ba811b821",
253
+ await dispatcher.query(
254
+ {
255
+ prompt: "next",
256
+ model: "anthropic/claude-sonnet-4-6",
257
+ system: "same-system",
258
+ timeout: 360_000,
259
+ preferredTokenId: 7,
260
+ imageGeneration: true,
261
+ runContext: {
262
+ threadCoord: {
263
+ workerId: 1,
264
+ threadId: "thread-1",
265
+ epoch: 0,
266
+ systemHash: "800ddd9ba811b821",
267
+ },
266
268
  },
267
269
  },
268
- });
270
+ abortSignal,
271
+ );
269
272
 
270
273
  const req = generate.mock.calls[0]![0];
274
+ expect(req).toMatchObject({ timeoutMs: 360_000, preferredTokenId: 7, imageGeneration: true });
275
+ expect(req.abortSignal).toBe(abortSignal);
271
276
  expect(req).not.toHaveProperty("reuse");
272
277
  expect(req).not.toHaveProperty("reuseInput");
273
278
  expect(req.coldInput).toEqual([{ type: "text", text: "next", text_elements: [] }]);
274
279
  });
275
280
 
276
- it("Anthropic query 는 내부 preferredTokenId 를 provider 로 전달한다", async () => {
281
+ it("Anthropic stream 은 실행 옵션과 delta/complete 를 보존하고 legacy reuse 필드는 제외한다", async () => {
277
282
  const dispatcher = new QgridDispatcherClass();
278
- const generate = vi.fn(async (_req: GenerateRequest) =>
279
- providerResult({ model: "claude-sonnet-4-6" }),
280
- );
281
- dispatcher.anthropicDispatcher = { generate } as never;
282
-
283
- await dispatcher.query({
284
- prompt: "keepalive",
285
- model: "anthropic/claude-haiku-4-5",
286
- preferredTokenId: 7,
287
- });
288
-
289
- expect(generate.mock.calls[0]![0].preferredTokenId).toBe(7);
290
- });
291
-
292
- it("Anthropic query 에도 imageGeneration 플래그를 전달해 provider 가 명시적으로 거부하게 한다", async () => {
293
- const dispatcher = new QgridDispatcherClass();
294
- const generate = vi.fn(async (_req: GenerateRequest) =>
295
- providerResult({ model: "claude-sonnet-4-6" }),
296
- );
297
- dispatcher.anthropicDispatcher = { generate } as never;
298
-
299
- await dispatcher.query({
300
- prompt: "draw",
301
- model: "anthropic/claude-sonnet-4-6",
302
- imageGeneration: true,
303
- });
304
-
305
- expect(generate.mock.calls[0]![0].imageGeneration).toBe(true);
306
- });
307
-
308
- it("Anthropic queryStream 도 reuse/reuseInput 을 provider 로 전달하지 않고 delta/complete 를 보존한다", async () => {
309
- const dispatcher = new QgridDispatcherClass();
310
- const generateStream = vi.fn(async (_req, cb) => {
283
+ const generateStream = vi.fn(async (_req: GenerateRequest, cb: GenerateStreamCallbacks) => {
311
284
  cb.onDelta("d");
312
285
  cb.onComplete(providerResult({ model: "claude-sonnet-4-6" }));
313
286
  });
314
287
  dispatcher.anthropicDispatcher = { generateStream } as never;
288
+ const abortSignal = new AbortController().signal;
315
289
 
316
290
  const onDelta = vi.fn();
317
291
  const onComplete = vi.fn();
@@ -320,6 +294,9 @@ describe("QgridDispatcherClass", () => {
320
294
  prompt: "next",
321
295
  model: "anthropic/claude-sonnet-4-6",
322
296
  system: "same-system",
297
+ timeout: 360_000,
298
+ preferredTokenId: 7,
299
+ imageGeneration: true,
323
300
  runContext: {
324
301
  threadCoord: {
325
302
  workerId: 1,
@@ -330,9 +307,12 @@ describe("QgridDispatcherClass", () => {
330
307
  },
331
308
  },
332
309
  { onDelta, onComplete, onError: vi.fn() },
310
+ abortSignal,
333
311
  );
334
312
 
335
313
  const req = generateStream.mock.calls[0]![0];
314
+ expect(req).toMatchObject({ timeoutMs: 360_000, preferredTokenId: 7, imageGeneration: true });
315
+ expect(req.abortSignal).toBe(abortSignal);
336
316
  expect(req).not.toHaveProperty("reuse");
337
317
  expect(req).not.toHaveProperty("reuseInput");
338
318
  expect(req.coldInput).toEqual([{ type: "text", text: "next", text_elements: [] }]);
@@ -347,42 +327,6 @@ describe("QgridDispatcherClass", () => {
347
327
  );
348
328
  });
349
329
 
350
- it("Anthropic queryStream 은 내부 preferredTokenId 를 provider 로 전달한다", async () => {
351
- const dispatcher = new QgridDispatcherClass();
352
- const generateStream = vi.fn(async (_req, cb) => {
353
- cb.onComplete(providerResult({ model: "claude-sonnet-4-6" }));
354
- });
355
- dispatcher.anthropicDispatcher = { generateStream } as never;
356
-
357
- await dispatcher.queryStream(
358
- {
359
- prompt: "keepalive",
360
- model: "anthropic/claude-haiku-4-5",
361
- preferredTokenId: 7,
362
- },
363
- { onDelta: vi.fn(), onComplete: vi.fn(), onError: vi.fn() },
364
- );
365
-
366
- expect(generateStream.mock.calls[0]![0].preferredTokenId).toBe(7);
367
- });
368
-
369
- it("Anthropic queryStream 에도 imageGeneration 플래그를 전달해 provider 가 명시적으로 거부하게 한다", async () => {
370
- const dispatcher = new QgridDispatcherClass();
371
- const generateStream = vi.fn(async (_req, _cb) => {});
372
- dispatcher.anthropicDispatcher = { generateStream } as never;
373
-
374
- await dispatcher.queryStream(
375
- {
376
- prompt: "draw",
377
- model: "anthropic/claude-sonnet-4-6",
378
- imageGeneration: true,
379
- },
380
- { onDelta: vi.fn(), onComplete: vi.fn(), onError: vi.fn() },
381
- );
382
-
383
- expect(generateStream.mock.calls[0]![0].imageGeneration).toBe(true);
384
- });
385
-
386
330
  it("jsonSchema 를 required + additionalProperties:false 로 strictify 한다", () => {
387
331
  const schema = buildStrictOutputSchema({
388
332
  jsonSchema: JSON.stringify({