@cartanova/qgrid-cli 2.7.0 → 2.7.2
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.
- package/README.ko.md +3 -2
- package/README.md +3 -2
- package/bundle/dist/_virtual/_rolldown/runtime.js +20 -1
- package/bundle/dist/application/monit/monit.frame.js +27 -14
- package/bundle/dist/application/monit/monit.types.js +22 -13
- package/bundle/dist/application/qgrid/conv-routing.js +21 -11
- package/bundle/dist/application/qgrid/oauth.js +1 -1
- package/bundle/dist/application/qgrid/qgrid-run-lifecycle.js +15 -4
- package/bundle/dist/application/qgrid/qgrid.dispatcher.js +34 -14
- package/bundle/dist/application/qgrid/qgrid.frame.js +50 -73
- package/bundle/dist/application/qgrid/qgrid.types.js +4 -1
- package/bundle/dist/application/qgrid/schema-prompt.js +240 -0
- package/bundle/dist/application/qgrid/token-subscriber.js +5 -5
- package/bundle/dist/application/qgrid/tool-emulation-schema.js +13 -1
- package/bundle/dist/application/qgrid/tool-emulation.js +8 -6
- package/bundle/dist/application/queries.generated.js +3 -1
- package/bundle/dist/application/request-log/json-schema-type-text.js +55 -0
- package/bundle/dist/application/request-log/request-log.model.js +85 -3
- package/bundle/dist/application/request-log/request-log.types.js +3 -2
- package/bundle/dist/application/request-log/zod-code-format.js +71 -0
- package/bundle/dist/application/setting/setting.constant.js +2 -62
- package/bundle/dist/application/setting/setting.model.js +3 -3
- package/bundle/dist/application/setting/setting.store.js +2 -2
- package/bundle/dist/application/sonamu.generated.js +11 -4
- package/bundle/dist/application/sonamu.generated.sso.js +7 -3
- package/bundle/dist/i18n/sd.generated.js +5 -2
- package/bundle/dist/migrations/20260814130113_alter_request_logs_add1_alter1.js +15 -0
- package/bundle/dist/migrations/20260814131051_alter_request_logs_add1_alter1.js +15 -0
- package/bundle/dist/migrations/20260814134846_alter_request_logs_add1_alter1.js +15 -0
- package/bundle/dist/migrations/20260814140759_alter_request_logs_alter1.js +13 -0
- package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/2020.js +112 -0
- package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/compile/codegen/code.js +140 -0
- package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/compile/codegen/index.js +676 -0
- package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/compile/codegen/scope.js +143 -0
- package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/compile/errors.js +104 -0
- package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/compile/index.js +225 -0
- package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/compile/names.js +30 -0
- package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/compile/ref_error.js +20 -0
- package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/compile/resolve.js +135 -0
- package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/compile/rules.js +63 -0
- package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/compile/util.js +148 -0
- package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/compile/validate/applicability.js +25 -0
- package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/compile/validate/boolSchema.js +50 -0
- package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/compile/validate/dataType.js +174 -0
- package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/compile/validate/defaults.js +33 -0
- package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/compile/validate/index.js +435 -0
- package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/compile/validate/keyword.js +115 -0
- package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/compile/validate/subschema.js +74 -0
- package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/core.js +585 -0
- package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/refs/data.js +20 -0
- package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/refs/json-schema-2020-12/index.js +44 -0
- package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/refs/json-schema-2020-12/meta/applicator.js +52 -0
- package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/refs/json-schema-2020-12/meta/content.js +22 -0
- package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/refs/json-schema-2020-12/meta/core.js +53 -0
- package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/refs/json-schema-2020-12/meta/format-annotation.js +18 -0
- package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/refs/json-schema-2020-12/meta/meta-data.js +38 -0
- package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/refs/json-schema-2020-12/meta/unevaluated.js +21 -0
- package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/refs/json-schema-2020-12/meta/validation.js +87 -0
- package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/refs/json-schema-2020-12/schema.js +61 -0
- package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/runtime/equal.js +14 -0
- package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/runtime/ucs2length.js +27 -0
- package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/runtime/uri.js +14 -0
- package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/runtime/validation_error.js +18 -0
- package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/applicator/additionalItems.js +59 -0
- package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/applicator/additionalProperties.js +98 -0
- package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/applicator/allOf.js +31 -0
- package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/applicator/anyOf.js +18 -0
- package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/applicator/contains.js +91 -0
- package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/applicator/dependencies.js +89 -0
- package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/applicator/dependentSchemas.js +18 -0
- package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/applicator/if.js +64 -0
- package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/applicator/index.js +62 -0
- package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/applicator/items.js +61 -0
- package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/applicator/items2020.js +36 -0
- package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/applicator/not.js +33 -0
- package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/applicator/oneOf.js +53 -0
- package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/applicator/patternProperties.js +63 -0
- package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/applicator/prefixItems.js +19 -0
- package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/applicator/properties.js +54 -0
- package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/applicator/propertyNames.js +43 -0
- package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/applicator/thenElse.js +19 -0
- package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/code.js +132 -0
- package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/core/id.js +16 -0
- package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/core/index.js +24 -0
- package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/core/ref.js +114 -0
- package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/discriminator/index.js +103 -0
- package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/discriminator/types.js +16 -0
- package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/draft2020.js +37 -0
- package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/dynamic/dynamicAnchor.js +48 -0
- package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/dynamic/dynamicRef.js +47 -0
- package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/dynamic/index.js +24 -0
- package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/dynamic/recursiveAnchor.js +22 -0
- package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/dynamic/recursiveRef.js +17 -0
- package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/format/format.js +94 -0
- package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/format/index.js +12 -0
- package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/metadata.js +25 -0
- package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/next.js +21 -0
- package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/unevaluated/index.js +15 -0
- package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/unevaluated/unevaluatedItems.js +48 -0
- package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/unevaluated/unevaluatedProperties.js +61 -0
- package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/validation/const.js +29 -0
- package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/validation/dependentRequired.js +19 -0
- package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/validation/enum.js +51 -0
- package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/validation/index.js +50 -0
- package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/validation/limitContains.js +20 -0
- package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/validation/limitItems.js +30 -0
- package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/validation/limitLength.js +35 -0
- package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/validation/limitNumber.js +49 -0
- package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/validation/limitProperties.js +30 -0
- package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/validation/multipleOf.js +29 -0
- package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/validation/pattern.js +40 -0
- package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/validation/required.js +74 -0
- package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/validation/uniqueItems.js +72 -0
- package/bundle/dist/node_modules/.pnpm/fast-deep-equal@3.1.3/node_modules/fast-deep-equal/index.js +35 -0
- package/bundle/dist/node_modules/.pnpm/fast-uri@3.1.0/node_modules/fast-uri/index.js +238 -0
- package/bundle/dist/node_modules/.pnpm/fast-uri@3.1.0/node_modules/fast-uri/lib/schemes.js +189 -0
- package/bundle/dist/node_modules/.pnpm/fast-uri@3.1.0/node_modules/fast-uri/lib/utils.js +284 -0
- package/bundle/dist/node_modules/.pnpm/json-schema-traverse@1.0.0/node_modules/json-schema-traverse/index.js +80 -0
- package/bundle/dist/node_modules/.pnpm/vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_vi_3892b4338df694f79f7d384fad23d930/node_modules/vitest/dist/chunks/_commonjsHelpers.D26ty3Ew.js +9 -0
- package/bundle/dist/node_modules/.pnpm/vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_vi_3892b4338df694f79f7d384fad23d930/node_modules/vitest/dist/chunks/benchmark.CX_oY03V.js +41 -0
- package/bundle/dist/node_modules/.pnpm/vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_vi_3892b4338df694f79f7d384fad23d930/node_modules/vitest/dist/chunks/evaluatedModules.Dg1zASAC.js +19 -0
- package/bundle/dist/node_modules/.pnpm/vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_vi_3892b4338df694f79f7d384fad23d930/node_modules/vitest/dist/chunks/index.Chj8NDwU.js +202 -0
- package/bundle/dist/node_modules/.pnpm/vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_vi_3892b4338df694f79f7d384fad23d930/node_modules/vitest/dist/chunks/index.DdgEv5B1.js +46 -0
- package/bundle/dist/node_modules/.pnpm/vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_vi_3892b4338df694f79f7d384fad23d930/node_modules/vitest/dist/chunks/rpc.MzXet3jl.js +119 -0
- package/bundle/dist/node_modules/.pnpm/vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_vi_3892b4338df694f79f7d384fad23d930/node_modules/vitest/dist/chunks/test.DNmyFkvJ.js +3044 -0
- package/bundle/dist/node_modules/.pnpm/vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_vi_3892b4338df694f79f7d384fad23d930/node_modules/vitest/dist/chunks/utils.BX5Fg8C4.js +59 -0
- package/bundle/dist/node_modules/.pnpm/vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_vi_3892b4338df694f79f7d384fad23d930/node_modules/vitest/dist/index.js +28 -0
- package/bundle/dist/sonamu.config.js +10 -9
- package/bundle/dist/testing/schema-bench.js +0 -0
- package/bundle/dist/testing/setup-mocks.js +2 -2
- package/bundle/dist/utils/providers/anthropic/anthropic-dispatcher.js +14 -2
- package/bundle/dist/utils/providers/anthropic/claude-session.js +1 -1
- package/bundle/dist/utils/providers/anthropic/fence-strip.js +83 -0
- package/bundle/dist/utils/providers/anthropic/stream-json-adapter.js +3 -5
- package/bundle/dist/utils/providers/common/model-cost.js +1 -1
- package/bundle/dist/utils/providers/common/schema-validation.js +1 -1
- package/bundle/dist/utils/providers/openai/openai-backend-protocol.js +144 -0
- package/bundle/dist/utils/providers/openai/openai-constants.js +4 -2
- package/bundle/dist/utils/providers/openai/openai-direct-client.js +327 -0
- package/bundle/dist/utils/providers/openai/openai-dispatcher.js +358 -781
- package/bundle/dist/utils/providers/openai/openai-oauth.js +84 -0
- package/bundle/dist/utils/providers/openai/openai-quota.js +76 -5
- package/bundle/dist/utils/providers/openai/openai-refresh.js +3 -3
- package/bundle/dist/utils/providers/openai/openai-sse.js +72 -0
- package/bundle/dist/utils/providers/openai/openai-transport-config.js +14 -0
- package/bundle/src/application/monit/monit.frame.test.ts +14 -17
- package/bundle/src/application/monit/monit.frame.ts +23 -12
- package/bundle/src/application/monit/monit.types.ts +40 -11
- package/bundle/src/application/qgrid/conv-routing.test.ts +67 -0
- package/bundle/src/application/qgrid/conv-routing.ts +46 -12
- package/bundle/src/application/qgrid/qgrid-oauth-redirect.test.ts +92 -2
- package/bundle/src/application/qgrid/qgrid-run-lifecycle.test.ts +3 -0
- package/bundle/src/application/qgrid/qgrid-run-lifecycle.ts +15 -1
- package/bundle/src/application/qgrid/qgrid.dispatcher.test.ts +286 -40
- package/bundle/src/application/qgrid/qgrid.dispatcher.ts +58 -14
- package/bundle/src/application/qgrid/qgrid.frame.test.ts +120 -153
- package/bundle/src/application/qgrid/qgrid.frame.ts +57 -94
- package/bundle/src/application/qgrid/qgrid.types.ts +11 -4
- package/bundle/src/application/qgrid/schema-prompt.test.ts +166 -0
- package/bundle/src/application/qgrid/schema-prompt.ts +293 -0
- package/bundle/src/application/qgrid/token-subscriber.ts +4 -4
- package/bundle/src/application/qgrid/tool-emulation-schema.ts +1 -1
- package/bundle/src/application/qgrid/tool-emulation.test.ts +37 -0
- package/bundle/src/application/qgrid/tool-emulation.ts +19 -7
- package/bundle/src/application/queries.generated.ts +6 -0
- package/bundle/src/application/request-log/json-schema-type-text.test.ts +96 -0
- package/bundle/src/application/request-log/json-schema-type-text.ts +83 -0
- package/bundle/src/application/request-log/request-log.entity.json +147 -21
- package/bundle/src/application/request-log/request-log.model.ts +108 -0
- package/bundle/src/application/request-log/request-log.types.ts +2 -0
- package/bundle/src/application/request-log/zod-code-format.test.ts +31 -0
- package/bundle/src/application/request-log/zod-code-format.ts +73 -0
- package/bundle/src/application/setting/setting.constant.test.ts +22 -24
- package/bundle/src/application/setting/setting.constant.ts +2 -63
- package/bundle/src/application/setting/setting.entity.json +1 -1
- package/bundle/src/application/setting/setting.store.ts +1 -1
- package/bundle/src/application/sonamu.generated.http +20 -1
- package/bundle/src/application/sonamu.generated.sso.ts +4 -0
- package/bundle/src/application/sonamu.generated.ts +10 -0
- package/bundle/src/i18n/sd.generated.ts +6 -1
- package/bundle/src/migrations/20260814130113_alter_request_logs_add1_alter1.ts +15 -0
- package/bundle/src/migrations/20260814131051_alter_request_logs_add1_alter1.ts +15 -0
- package/bundle/src/migrations/20260814134846_alter_request_logs_add1_alter1.ts +15 -0
- package/bundle/src/migrations/20260814140759_alter_request_logs_alter1.ts +13 -0
- package/bundle/src/sonamu.config.ts +9 -13
- package/bundle/src/testing/schema-bench.test.ts +358 -0
- package/bundle/src/testing/schema-bench.ts +352 -0
- package/bundle/src/utils/providers/anthropic/anthropic-dispatcher.ts +17 -2
- package/bundle/src/utils/providers/anthropic/claude-session.ts +1 -3
- package/bundle/src/utils/providers/anthropic/fence-strip.test.ts +122 -0
- package/bundle/src/utils/providers/anthropic/fence-strip.ts +105 -0
- package/bundle/src/utils/providers/anthropic/stream-json-adapter.test.ts +1 -2
- package/bundle/src/utils/providers/anthropic/stream-json-adapter.ts +4 -11
- package/bundle/src/utils/providers/common/model-cost.ts +4 -9
- package/bundle/src/utils/providers/common/provider-dispatcher.ts +10 -8
- package/bundle/src/utils/providers/common/provider-types.ts +48 -0
- package/bundle/src/utils/providers/common/schema-validation.ts +1 -1
- package/bundle/src/utils/providers/openai/openai-backend-protocol.test.ts +106 -0
- package/bundle/src/utils/providers/openai/openai-backend-protocol.ts +255 -0
- package/bundle/src/utils/providers/openai/openai-constants.ts +2 -0
- package/bundle/src/utils/providers/openai/openai-direct-client.test.ts +610 -0
- package/bundle/src/utils/providers/openai/openai-direct-client.ts +478 -0
- package/bundle/src/utils/providers/openai/openai-dispatcher.test.ts +336 -1723
- package/bundle/src/utils/providers/openai/openai-dispatcher.ts +458 -1175
- package/bundle/src/utils/providers/openai/openai-oauth.test.ts +95 -0
- package/bundle/src/utils/providers/openai/openai-oauth.ts +141 -0
- package/bundle/src/utils/providers/openai/openai-quota.test.ts +80 -7
- package/bundle/src/utils/providers/openai/openai-quota.ts +105 -4
- package/bundle/src/utils/providers/openai/openai-refresh.test.ts +120 -0
- package/bundle/src/utils/providers/openai/openai-refresh.ts +3 -1
- package/bundle/src/utils/providers/openai/openai-sse.test.ts +52 -0
- package/bundle/src/utils/providers/openai/openai-sse.ts +79 -0
- package/bundle/src/utils/providers/openai/openai-transport-config.ts +17 -0
- package/bundle/web-dist/client/assets/index-BldeEvAK.css +1 -0
- package/bundle/web-dist/client/assets/index-DkAXPF9q.js +106 -0
- package/bundle/web-dist/client/assets/logs-DlI6OojL.js +1 -0
- package/bundle/web-dist/client/assets/monit-qap66dhi.js +1 -0
- package/bundle/web-dist/client/assets/routes-CV07Pzde.js +5 -0
- package/bundle/web-dist/client/assets/services.generated-CSW8bhCP.js +51 -0
- package/bundle/web-dist/client/assets/settings-CdYub4yo.js +1 -0
- package/bundle/web-dist/client/assets/show-DA1L8DVD.js +2 -0
- package/bundle/web-dist/client/assets/tokens-Dt3gfkwP.js +1 -0
- package/bundle/web-dist/client/assets/use-oauth-login-flow-Cwi0HtJY.js +1 -0
- package/bundle/web-dist/client/index.html +3 -3
- package/bundle/web-dist/server/assets/lazyRouteComponent-0y-znAfz.js +1856 -0
- package/bundle/web-dist/server/assets/logs-CJBbHM3_.js +481 -0
- package/bundle/web-dist/server/assets/monit-8WAsPETB.js +1670 -0
- package/bundle/web-dist/server/assets/plus-9das21ju.js +19 -0
- package/bundle/web-dist/server/assets/react-dom-zmEq8BVp.js +462 -0
- package/bundle/web-dist/server/assets/routes-B6bX3o41.js +2924 -0
- package/bundle/web-dist/server/assets/services.generated-DyPeBI00.js +23644 -0
- package/bundle/web-dist/server/assets/settings-D1u5WdpP.js +597 -0
- package/bundle/web-dist/server/assets/show-Cr7vwR0l.js +2861 -0
- package/bundle/web-dist/server/assets/tokens-BumM0gnH.js +441 -0
- package/bundle/web-dist/server/assets/use-oauth-login-flow-DmsHGOlx.js +160 -0
- package/bundle/web-dist/server/entry-server.generated.js +12 -12
- package/dist/cli.d.ts +10 -1
- package/dist/cli.js +1 -6
- package/package.json +3 -2
- package/skills/qgrid/SKILL.md +5 -5
- package/skills/qgrid/references/ai-sdk-provider-contract.md +36 -25
- package/skills/qgrid/references/anthropic-claude-code-runtime.md +31 -14
- package/skills/qgrid/references/cli-env-and-server-boot.md +6 -13
- package/skills/qgrid/references/decision-rationale.md +28 -26
- package/skills/qgrid/references/docs-workflow.md +1 -1
- package/skills/qgrid/references/openai-codex-runtime.md +39 -156
- package/skills/qgrid/references/prompt-cache-and-usage.md +35 -68
- package/skills/qgrid/references/provider-runtime-differences.md +18 -18
- package/skills/qgrid/references/repo-map.md +2 -2
- package/skills/qgrid/references/request-log-run-lifecycle.md +12 -2
- package/skills/qgrid/references/sonamu-api-web-flow.md +4 -0
- package/skills/qgrid/references/token-auth-quota-lifecycle.md +14 -24
- package/skills/qgrid/references/tool-calling-and-multiturn.md +19 -9
- package/skills/qgrid/references/verification-and-debugging.md +17 -15
- package/bundle/dist/codex-protocol/AgentPath.js +0 -1
- package/bundle/dist/codex-protocol/ApplyPatchApprovalParams.js +0 -1
- package/bundle/dist/codex-protocol/ApplyPatchApprovalResponse.js +0 -1
- package/bundle/dist/codex-protocol/AuthMode.js +0 -1
- package/bundle/dist/codex-protocol/ClientInfo.js +0 -1
- package/bundle/dist/codex-protocol/ClientNotification.js +0 -1
- package/bundle/dist/codex-protocol/ClientRequest.js +0 -1
- package/bundle/dist/codex-protocol/CollaborationMode.js +0 -1
- package/bundle/dist/codex-protocol/ContentItem.js +0 -1
- package/bundle/dist/codex-protocol/ConversationGitInfo.js +0 -1
- package/bundle/dist/codex-protocol/ConversationSummary.js +0 -1
- package/bundle/dist/codex-protocol/ExecCommandApprovalParams.js +0 -1
- package/bundle/dist/codex-protocol/ExecCommandApprovalResponse.js +0 -1
- package/bundle/dist/codex-protocol/ExecPolicyAmendment.js +0 -1
- package/bundle/dist/codex-protocol/FileChange.js +0 -1
- package/bundle/dist/codex-protocol/ForcedLoginMethod.js +0 -1
- package/bundle/dist/codex-protocol/FunctionCallOutputBody.js +0 -1
- package/bundle/dist/codex-protocol/FunctionCallOutputContentItem.js +0 -1
- package/bundle/dist/codex-protocol/FuzzyFileSearchMatchType.js +0 -1
- package/bundle/dist/codex-protocol/FuzzyFileSearchParams.js +0 -1
- package/bundle/dist/codex-protocol/FuzzyFileSearchResponse.js +0 -1
- package/bundle/dist/codex-protocol/FuzzyFileSearchResult.js +0 -1
- package/bundle/dist/codex-protocol/FuzzyFileSearchSessionCompletedNotification.js +0 -1
- package/bundle/dist/codex-protocol/FuzzyFileSearchSessionUpdatedNotification.js +0 -1
- package/bundle/dist/codex-protocol/GetAuthStatusParams.js +0 -1
- package/bundle/dist/codex-protocol/GetAuthStatusResponse.js +0 -1
- package/bundle/dist/codex-protocol/GetConversationSummaryParams.js +0 -1
- package/bundle/dist/codex-protocol/GetConversationSummaryResponse.js +0 -1
- package/bundle/dist/codex-protocol/GitDiffToRemoteParams.js +0 -1
- package/bundle/dist/codex-protocol/GitDiffToRemoteResponse.js +0 -1
- package/bundle/dist/codex-protocol/GitSha.js +0 -1
- package/bundle/dist/codex-protocol/ImageDetail.js +0 -1
- package/bundle/dist/codex-protocol/InitializeCapabilities.js +0 -1
- package/bundle/dist/codex-protocol/InitializeParams.js +0 -1
- package/bundle/dist/codex-protocol/InitializeResponse.js +0 -1
- package/bundle/dist/codex-protocol/InputModality.js +0 -1
- package/bundle/dist/codex-protocol/InternalSessionSource.js +0 -1
- package/bundle/dist/codex-protocol/LocalShellAction.js +0 -1
- package/bundle/dist/codex-protocol/LocalShellExecAction.js +0 -1
- package/bundle/dist/codex-protocol/LocalShellStatus.js +0 -1
- package/bundle/dist/codex-protocol/MessagePhase.js +0 -1
- package/bundle/dist/codex-protocol/ModeKind.js +0 -1
- package/bundle/dist/codex-protocol/NetworkPolicyAmendment.js +0 -1
- package/bundle/dist/codex-protocol/NetworkPolicyRuleAction.js +0 -1
- package/bundle/dist/codex-protocol/ParsedCommand.js +0 -1
- package/bundle/dist/codex-protocol/Personality.js +0 -1
- package/bundle/dist/codex-protocol/PlanType.js +0 -1
- package/bundle/dist/codex-protocol/RealtimeConversationVersion.js +0 -1
- package/bundle/dist/codex-protocol/RealtimeOutputModality.js +0 -1
- package/bundle/dist/codex-protocol/RealtimeVoice.js +0 -1
- package/bundle/dist/codex-protocol/RealtimeVoicesList.js +0 -1
- package/bundle/dist/codex-protocol/ReasoningEffort.js +0 -1
- package/bundle/dist/codex-protocol/ReasoningItemContent.js +0 -1
- package/bundle/dist/codex-protocol/ReasoningItemReasoningSummary.js +0 -1
- package/bundle/dist/codex-protocol/ReasoningSummary.js +0 -1
- package/bundle/dist/codex-protocol/RequestId.js +0 -1
- package/bundle/dist/codex-protocol/Resource.js +0 -1
- package/bundle/dist/codex-protocol/ResourceContent.js +0 -1
- package/bundle/dist/codex-protocol/ResourceTemplate.js +0 -1
- package/bundle/dist/codex-protocol/ResponseItem.js +0 -1
- package/bundle/dist/codex-protocol/ReviewDecision.js +0 -1
- package/bundle/dist/codex-protocol/ServerNotification.js +0 -1
- package/bundle/dist/codex-protocol/ServerRequest.js +0 -1
- package/bundle/dist/codex-protocol/SessionSource.js +0 -1
- package/bundle/dist/codex-protocol/Settings.js +0 -1
- package/bundle/dist/codex-protocol/SubAgentSource.js +0 -1
- package/bundle/dist/codex-protocol/ThreadId.js +0 -1
- package/bundle/dist/codex-protocol/ThreadMemoryMode.js +0 -1
- package/bundle/dist/codex-protocol/Tool.js +0 -1
- package/bundle/dist/codex-protocol/Verbosity.js +0 -1
- package/bundle/dist/codex-protocol/WebSearchAction.js +0 -1
- package/bundle/dist/codex-protocol/WebSearchContextSize.js +0 -1
- package/bundle/dist/codex-protocol/WebSearchLocation.js +0 -1
- package/bundle/dist/codex-protocol/WebSearchMode.js +0 -1
- package/bundle/dist/codex-protocol/WebSearchToolConfig.js +0 -1
- package/bundle/dist/codex-protocol/index.js +0 -2
- package/bundle/dist/codex-protocol/serde_json/JsonValue.js +0 -1
- package/bundle/dist/codex-protocol/v2/Account.js +0 -1
- package/bundle/dist/codex-protocol/v2/AccountLoginCompletedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/AccountRateLimitsUpdatedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/AccountUpdatedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ActivePermissionProfile.js +0 -1
- package/bundle/dist/codex-protocol/v2/ActivePermissionProfileModification.js +0 -1
- package/bundle/dist/codex-protocol/v2/AddCreditsNudgeCreditType.js +0 -1
- package/bundle/dist/codex-protocol/v2/AddCreditsNudgeEmailStatus.js +0 -1
- package/bundle/dist/codex-protocol/v2/AdditionalFileSystemPermissions.js +0 -1
- package/bundle/dist/codex-protocol/v2/AdditionalNetworkPermissions.js +0 -1
- package/bundle/dist/codex-protocol/v2/AdditionalPermissionProfile.js +0 -1
- package/bundle/dist/codex-protocol/v2/AgentMessageDeltaNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/AnalyticsConfig.js +0 -1
- package/bundle/dist/codex-protocol/v2/AppBranding.js +0 -1
- package/bundle/dist/codex-protocol/v2/AppInfo.js +0 -1
- package/bundle/dist/codex-protocol/v2/AppListUpdatedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/AppMetadata.js +0 -1
- package/bundle/dist/codex-protocol/v2/AppReview.js +0 -1
- package/bundle/dist/codex-protocol/v2/AppScreenshot.js +0 -1
- package/bundle/dist/codex-protocol/v2/AppSummary.js +0 -1
- package/bundle/dist/codex-protocol/v2/AppToolApproval.js +0 -1
- package/bundle/dist/codex-protocol/v2/AppToolsConfig.js +0 -1
- package/bundle/dist/codex-protocol/v2/ApprovalsReviewer.js +0 -1
- package/bundle/dist/codex-protocol/v2/AppsConfig.js +0 -1
- package/bundle/dist/codex-protocol/v2/AppsDefaultConfig.js +0 -1
- package/bundle/dist/codex-protocol/v2/AppsListParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/AppsListResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/AskForApproval.js +0 -1
- package/bundle/dist/codex-protocol/v2/AutoReviewDecisionSource.js +0 -1
- package/bundle/dist/codex-protocol/v2/ByteRange.js +0 -1
- package/bundle/dist/codex-protocol/v2/CancelLoginAccountParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/CancelLoginAccountResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/CancelLoginAccountStatus.js +0 -1
- package/bundle/dist/codex-protocol/v2/ChatgptAuthTokensRefreshParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ChatgptAuthTokensRefreshReason.js +0 -1
- package/bundle/dist/codex-protocol/v2/ChatgptAuthTokensRefreshResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/CodexErrorInfo.js +0 -1
- package/bundle/dist/codex-protocol/v2/CollabAgentState.js +0 -1
- package/bundle/dist/codex-protocol/v2/CollabAgentStatus.js +0 -1
- package/bundle/dist/codex-protocol/v2/CollabAgentTool.js +0 -1
- package/bundle/dist/codex-protocol/v2/CollabAgentToolCallStatus.js +0 -1
- package/bundle/dist/codex-protocol/v2/CollaborationModeMask.js +0 -1
- package/bundle/dist/codex-protocol/v2/CommandAction.js +0 -1
- package/bundle/dist/codex-protocol/v2/CommandExecOutputDeltaNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/CommandExecOutputStream.js +0 -1
- package/bundle/dist/codex-protocol/v2/CommandExecParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/CommandExecResizeParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/CommandExecResizeResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/CommandExecResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/CommandExecTerminalSize.js +0 -1
- package/bundle/dist/codex-protocol/v2/CommandExecTerminateParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/CommandExecTerminateResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/CommandExecWriteParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/CommandExecWriteResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/CommandExecutionApprovalDecision.js +0 -1
- package/bundle/dist/codex-protocol/v2/CommandExecutionOutputDeltaNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/CommandExecutionRequestApprovalParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/CommandExecutionRequestApprovalResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/CommandExecutionSource.js +0 -1
- package/bundle/dist/codex-protocol/v2/CommandExecutionStatus.js +0 -1
- package/bundle/dist/codex-protocol/v2/CommandMigration.js +0 -1
- package/bundle/dist/codex-protocol/v2/Config.js +0 -1
- package/bundle/dist/codex-protocol/v2/ConfigBatchWriteParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ConfigEdit.js +0 -1
- package/bundle/dist/codex-protocol/v2/ConfigLayer.js +0 -1
- package/bundle/dist/codex-protocol/v2/ConfigLayerMetadata.js +0 -1
- package/bundle/dist/codex-protocol/v2/ConfigLayerSource.js +0 -1
- package/bundle/dist/codex-protocol/v2/ConfigReadParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ConfigReadResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ConfigRequirements.js +0 -1
- package/bundle/dist/codex-protocol/v2/ConfigRequirementsReadResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ConfigValueWriteParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ConfigWarningNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ConfigWriteResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ConfiguredHookHandler.js +0 -1
- package/bundle/dist/codex-protocol/v2/ConfiguredHookMatcherGroup.js +0 -1
- package/bundle/dist/codex-protocol/v2/ContextCompactedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/CreditsSnapshot.js +0 -1
- package/bundle/dist/codex-protocol/v2/DeprecationNoticeNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/DynamicToolCallOutputContentItem.js +0 -1
- package/bundle/dist/codex-protocol/v2/DynamicToolCallParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/DynamicToolCallResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/DynamicToolCallStatus.js +0 -1
- package/bundle/dist/codex-protocol/v2/DynamicToolSpec.js +0 -1
- package/bundle/dist/codex-protocol/v2/ErrorNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ExecPolicyAmendment.js +0 -1
- package/bundle/dist/codex-protocol/v2/ExperimentalFeature.js +0 -1
- package/bundle/dist/codex-protocol/v2/ExperimentalFeatureEnablementSetParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ExperimentalFeatureEnablementSetResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ExperimentalFeatureListParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ExperimentalFeatureListResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ExperimentalFeatureStage.js +0 -1
- package/bundle/dist/codex-protocol/v2/ExternalAgentConfigDetectParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ExternalAgentConfigDetectResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ExternalAgentConfigImportCompletedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ExternalAgentConfigImportParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ExternalAgentConfigImportResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ExternalAgentConfigMigrationItem.js +0 -1
- package/bundle/dist/codex-protocol/v2/ExternalAgentConfigMigrationItemType.js +0 -1
- package/bundle/dist/codex-protocol/v2/FeedbackUploadParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/FeedbackUploadResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/FileChangeApprovalDecision.js +0 -1
- package/bundle/dist/codex-protocol/v2/FileChangeOutputDeltaNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/FileChangePatchUpdatedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/FileChangeRequestApprovalParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/FileChangeRequestApprovalResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/FileSystemAccessMode.js +0 -1
- package/bundle/dist/codex-protocol/v2/FileSystemPath.js +0 -1
- package/bundle/dist/codex-protocol/v2/FileSystemSandboxEntry.js +0 -1
- package/bundle/dist/codex-protocol/v2/FileSystemSpecialPath.js +0 -1
- package/bundle/dist/codex-protocol/v2/FileUpdateChange.js +0 -1
- package/bundle/dist/codex-protocol/v2/FsChangedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/FsCopyParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/FsCopyResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/FsCreateDirectoryParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/FsCreateDirectoryResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/FsGetMetadataParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/FsGetMetadataResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/FsReadDirectoryEntry.js +0 -1
- package/bundle/dist/codex-protocol/v2/FsReadDirectoryParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/FsReadDirectoryResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/FsReadFileParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/FsReadFileResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/FsRemoveParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/FsRemoveResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/FsUnwatchParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/FsUnwatchResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/FsWatchParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/FsWatchResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/FsWriteFileParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/FsWriteFileResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/GetAccountParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/GetAccountRateLimitsResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/GetAccountResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/GitInfo.js +0 -1
- package/bundle/dist/codex-protocol/v2/GrantedPermissionProfile.js +0 -1
- package/bundle/dist/codex-protocol/v2/GuardianApprovalReview.js +0 -1
- package/bundle/dist/codex-protocol/v2/GuardianApprovalReviewAction.js +0 -1
- package/bundle/dist/codex-protocol/v2/GuardianApprovalReviewStatus.js +0 -1
- package/bundle/dist/codex-protocol/v2/GuardianCommandSource.js +0 -1
- package/bundle/dist/codex-protocol/v2/GuardianRiskLevel.js +0 -1
- package/bundle/dist/codex-protocol/v2/GuardianUserAuthorization.js +0 -1
- package/bundle/dist/codex-protocol/v2/GuardianWarningNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/HookCompletedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/HookErrorInfo.js +0 -1
- package/bundle/dist/codex-protocol/v2/HookEventName.js +0 -1
- package/bundle/dist/codex-protocol/v2/HookExecutionMode.js +0 -1
- package/bundle/dist/codex-protocol/v2/HookHandlerType.js +0 -1
- package/bundle/dist/codex-protocol/v2/HookMetadata.js +0 -1
- package/bundle/dist/codex-protocol/v2/HookMigration.js +0 -1
- package/bundle/dist/codex-protocol/v2/HookOutputEntry.js +0 -1
- package/bundle/dist/codex-protocol/v2/HookOutputEntryKind.js +0 -1
- package/bundle/dist/codex-protocol/v2/HookPromptFragment.js +0 -1
- package/bundle/dist/codex-protocol/v2/HookRunStatus.js +0 -1
- package/bundle/dist/codex-protocol/v2/HookRunSummary.js +0 -1
- package/bundle/dist/codex-protocol/v2/HookScope.js +0 -1
- package/bundle/dist/codex-protocol/v2/HookSource.js +0 -1
- package/bundle/dist/codex-protocol/v2/HookStartedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/HookTrustStatus.js +0 -1
- package/bundle/dist/codex-protocol/v2/HooksListEntry.js +0 -1
- package/bundle/dist/codex-protocol/v2/HooksListParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/HooksListResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ItemCompletedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ItemGuardianApprovalReviewCompletedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ItemGuardianApprovalReviewStartedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ItemStartedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ListMcpServerStatusParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ListMcpServerStatusResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/LoginAccountParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/LoginAccountResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/LogoutAccountResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ManagedHooksRequirements.js +0 -1
- package/bundle/dist/codex-protocol/v2/MarketplaceAddParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/MarketplaceAddResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/MarketplaceInterface.js +0 -1
- package/bundle/dist/codex-protocol/v2/MarketplaceLoadErrorInfo.js +0 -1
- package/bundle/dist/codex-protocol/v2/MarketplaceRemoveParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/MarketplaceRemoveResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/MarketplaceUpgradeErrorInfo.js +0 -1
- package/bundle/dist/codex-protocol/v2/MarketplaceUpgradeParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/MarketplaceUpgradeResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpAuthStatus.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpElicitationArrayType.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpElicitationBooleanSchema.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpElicitationBooleanType.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpElicitationConstOption.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpElicitationEnumSchema.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpElicitationLegacyTitledEnumSchema.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpElicitationMultiSelectEnumSchema.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpElicitationNumberSchema.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpElicitationNumberType.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpElicitationObjectType.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpElicitationPrimitiveSchema.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpElicitationSchema.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpElicitationSingleSelectEnumSchema.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpElicitationStringFormat.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpElicitationStringSchema.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpElicitationStringType.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpElicitationTitledEnumItems.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpElicitationTitledMultiSelectEnumSchema.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpElicitationTitledSingleSelectEnumSchema.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpElicitationUntitledEnumItems.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpElicitationUntitledMultiSelectEnumSchema.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpElicitationUntitledSingleSelectEnumSchema.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpResourceReadParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpResourceReadResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpServerElicitationAction.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpServerElicitationRequestParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpServerElicitationRequestResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpServerMigration.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpServerOauthLoginCompletedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpServerOauthLoginParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpServerOauthLoginResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpServerRefreshResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpServerStartupState.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpServerStatus.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpServerStatusDetail.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpServerStatusUpdatedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpServerToolCallParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpServerToolCallResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpToolCallError.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpToolCallProgressNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpToolCallResult.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpToolCallStatus.js +0 -1
- package/bundle/dist/codex-protocol/v2/MemoryCitation.js +0 -1
- package/bundle/dist/codex-protocol/v2/MemoryCitationEntry.js +0 -1
- package/bundle/dist/codex-protocol/v2/MergeStrategy.js +0 -1
- package/bundle/dist/codex-protocol/v2/MigrationDetails.js +0 -1
- package/bundle/dist/codex-protocol/v2/Model.js +0 -1
- package/bundle/dist/codex-protocol/v2/ModelAvailabilityNux.js +0 -1
- package/bundle/dist/codex-protocol/v2/ModelListParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ModelListResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ModelProviderCapabilitiesReadParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ModelProviderCapabilitiesReadResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ModelRerouteReason.js +0 -1
- package/bundle/dist/codex-protocol/v2/ModelReroutedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ModelServiceTier.js +0 -1
- package/bundle/dist/codex-protocol/v2/ModelUpgradeInfo.js +0 -1
- package/bundle/dist/codex-protocol/v2/ModelVerification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ModelVerificationNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/NetworkAccess.js +0 -1
- package/bundle/dist/codex-protocol/v2/NetworkApprovalContext.js +0 -1
- package/bundle/dist/codex-protocol/v2/NetworkApprovalProtocol.js +0 -1
- package/bundle/dist/codex-protocol/v2/NetworkDomainPermission.js +0 -1
- package/bundle/dist/codex-protocol/v2/NetworkPolicyAmendment.js +0 -1
- package/bundle/dist/codex-protocol/v2/NetworkPolicyRuleAction.js +0 -1
- package/bundle/dist/codex-protocol/v2/NetworkRequirements.js +0 -1
- package/bundle/dist/codex-protocol/v2/NetworkUnixSocketPermission.js +0 -1
- package/bundle/dist/codex-protocol/v2/NonSteerableTurnKind.js +0 -1
- package/bundle/dist/codex-protocol/v2/OverriddenMetadata.js +0 -1
- package/bundle/dist/codex-protocol/v2/PatchApplyStatus.js +0 -1
- package/bundle/dist/codex-protocol/v2/PatchChangeKind.js +0 -1
- package/bundle/dist/codex-protocol/v2/PermissionGrantScope.js +0 -1
- package/bundle/dist/codex-protocol/v2/PermissionProfile.js +0 -1
- package/bundle/dist/codex-protocol/v2/PermissionProfileFileSystemPermissions.js +0 -1
- package/bundle/dist/codex-protocol/v2/PermissionProfileModificationParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/PermissionProfileNetworkPermissions.js +0 -1
- package/bundle/dist/codex-protocol/v2/PermissionProfileSelectionParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/PermissionsRequestApprovalParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/PermissionsRequestApprovalResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/PlanDeltaNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginAuthPolicy.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginAvailability.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginDetail.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginHookSummary.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginInstallParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginInstallPolicy.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginInstallResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginInterface.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginListMarketplaceKind.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginListParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginListResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginMarketplaceEntry.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginReadParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginReadResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginShareContext.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginShareDeleteParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginShareDeleteResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginShareDiscoverability.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginShareListItem.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginShareListParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginShareListResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginSharePrincipal.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginSharePrincipalType.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginShareSaveParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginShareSaveResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginShareTarget.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginShareUpdateDiscoverability.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginShareUpdateTargetsParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginShareUpdateTargetsResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginSkillReadParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginSkillReadResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginSource.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginSummary.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginUninstallParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginUninstallResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginsMigration.js +0 -1
- package/bundle/dist/codex-protocol/v2/ProcessExitedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ProcessOutputDeltaNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ProcessOutputStream.js +0 -1
- package/bundle/dist/codex-protocol/v2/ProcessTerminalSize.js +0 -1
- package/bundle/dist/codex-protocol/v2/ProfileV2.js +0 -1
- package/bundle/dist/codex-protocol/v2/RateLimitReachedType.js +0 -1
- package/bundle/dist/codex-protocol/v2/RateLimitSnapshot.js +0 -1
- package/bundle/dist/codex-protocol/v2/RateLimitWindow.js +0 -1
- package/bundle/dist/codex-protocol/v2/RawResponseItemCompletedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ReasoningEffortOption.js +0 -1
- package/bundle/dist/codex-protocol/v2/ReasoningSummaryPartAddedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ReasoningSummaryTextDeltaNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ReasoningTextDeltaNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/RemoteControlConnectionStatus.js +0 -1
- package/bundle/dist/codex-protocol/v2/RemoteControlStatusChangedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/RequestPermissionProfile.js +0 -1
- package/bundle/dist/codex-protocol/v2/ResidencyRequirement.js +0 -1
- package/bundle/dist/codex-protocol/v2/ReviewDelivery.js +0 -1
- package/bundle/dist/codex-protocol/v2/ReviewStartParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ReviewStartResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ReviewTarget.js +0 -1
- package/bundle/dist/codex-protocol/v2/SandboxMode.js +0 -1
- package/bundle/dist/codex-protocol/v2/SandboxPolicy.js +0 -1
- package/bundle/dist/codex-protocol/v2/SandboxWorkspaceWrite.js +0 -1
- package/bundle/dist/codex-protocol/v2/SendAddCreditsNudgeEmailParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/SendAddCreditsNudgeEmailResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ServerRequestResolvedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/SessionMigration.js +0 -1
- package/bundle/dist/codex-protocol/v2/SessionSource.js +0 -1
- package/bundle/dist/codex-protocol/v2/SkillDependencies.js +0 -1
- package/bundle/dist/codex-protocol/v2/SkillErrorInfo.js +0 -1
- package/bundle/dist/codex-protocol/v2/SkillInterface.js +0 -1
- package/bundle/dist/codex-protocol/v2/SkillMetadata.js +0 -1
- package/bundle/dist/codex-protocol/v2/SkillScope.js +0 -1
- package/bundle/dist/codex-protocol/v2/SkillSummary.js +0 -1
- package/bundle/dist/codex-protocol/v2/SkillToolDependency.js +0 -1
- package/bundle/dist/codex-protocol/v2/SkillsChangedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/SkillsConfigWriteParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/SkillsConfigWriteResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/SkillsListEntry.js +0 -1
- package/bundle/dist/codex-protocol/v2/SkillsListParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/SkillsListResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/SortDirection.js +0 -1
- package/bundle/dist/codex-protocol/v2/SubagentMigration.js +0 -1
- package/bundle/dist/codex-protocol/v2/TerminalInteractionNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/TextElement.js +0 -1
- package/bundle/dist/codex-protocol/v2/TextPosition.js +0 -1
- package/bundle/dist/codex-protocol/v2/TextRange.js +0 -1
- package/bundle/dist/codex-protocol/v2/Thread.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadActiveFlag.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadApproveGuardianDeniedActionParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadApproveGuardianDeniedActionResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadArchiveParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadArchiveResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadArchivedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadClosedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadCompactStartParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadCompactStartResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadForkParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadForkResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadGoal.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadGoalClearedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadGoalStatus.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadGoalUpdatedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadInjectItemsParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadInjectItemsResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadItem.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadListParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadListResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadLoadedListParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadLoadedListResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadMetadataGitInfoUpdateParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadMetadataUpdateParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadMetadataUpdateResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadNameUpdatedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadReadParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadReadResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadRealtimeAudioChunk.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadRealtimeClosedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadRealtimeErrorNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadRealtimeItemAddedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadRealtimeOutputAudioDeltaNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadRealtimeSdpNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadRealtimeStartTransport.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadRealtimeStartedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadRealtimeTranscriptDeltaNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadRealtimeTranscriptDoneNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadResumeParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadResumeResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadRollbackParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadRollbackResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadSetNameParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadSetNameResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadShellCommandParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadShellCommandResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadSortKey.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadSource.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadSourceKind.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadStartParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadStartResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadStartSource.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadStartedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadStatus.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadStatusChangedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadTokenUsage.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadTokenUsageUpdatedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadUnarchiveParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadUnarchiveResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadUnarchivedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadUnsubscribeParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadUnsubscribeResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadUnsubscribeStatus.js +0 -1
- package/bundle/dist/codex-protocol/v2/TokenUsageBreakdown.js +0 -1
- package/bundle/dist/codex-protocol/v2/ToolRequestUserInputAnswer.js +0 -1
- package/bundle/dist/codex-protocol/v2/ToolRequestUserInputOption.js +0 -1
- package/bundle/dist/codex-protocol/v2/ToolRequestUserInputParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ToolRequestUserInputQuestion.js +0 -1
- package/bundle/dist/codex-protocol/v2/ToolRequestUserInputResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ToolsV2.js +0 -1
- package/bundle/dist/codex-protocol/v2/Turn.js +0 -1
- package/bundle/dist/codex-protocol/v2/TurnCompletedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/TurnDiffUpdatedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/TurnEnvironmentParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/TurnError.js +0 -1
- package/bundle/dist/codex-protocol/v2/TurnInterruptParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/TurnInterruptResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/TurnItemsView.js +0 -1
- package/bundle/dist/codex-protocol/v2/TurnPlanStep.js +0 -1
- package/bundle/dist/codex-protocol/v2/TurnPlanStepStatus.js +0 -1
- package/bundle/dist/codex-protocol/v2/TurnPlanUpdatedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/TurnStartParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/TurnStartResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/TurnStartedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/TurnStatus.js +0 -1
- package/bundle/dist/codex-protocol/v2/TurnSteerParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/TurnSteerResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/UserInput.js +0 -1
- package/bundle/dist/codex-protocol/v2/WarningNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/WebSearchAction.js +0 -1
- package/bundle/dist/codex-protocol/v2/WindowsSandboxReadiness.js +0 -1
- package/bundle/dist/codex-protocol/v2/WindowsSandboxReadinessResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/WindowsSandboxSetupCompletedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/WindowsSandboxSetupMode.js +0 -1
- package/bundle/dist/codex-protocol/v2/WindowsSandboxSetupStartParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/WindowsSandboxSetupStartResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/WindowsWorldWritableWarningNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/WriteStatus.js +0 -1
- package/bundle/dist/codex-protocol/v2/index.js +0 -7
- package/bundle/dist/node_modules/.pnpm/vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_ms_f9cfcfeddd63e656d4010c98521af26c/node_modules/vitest/dist/chunks/_commonjsHelpers.D26ty3Ew.js +0 -9
- package/bundle/dist/node_modules/.pnpm/vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_ms_f9cfcfeddd63e656d4010c98521af26c/node_modules/vitest/dist/chunks/benchmark.CX_oY03V.js +0 -41
- package/bundle/dist/node_modules/.pnpm/vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_ms_f9cfcfeddd63e656d4010c98521af26c/node_modules/vitest/dist/chunks/evaluatedModules.Dg1zASAC.js +0 -19
- package/bundle/dist/node_modules/.pnpm/vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_ms_f9cfcfeddd63e656d4010c98521af26c/node_modules/vitest/dist/chunks/index.Chj8NDwU.js +0 -202
- package/bundle/dist/node_modules/.pnpm/vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_ms_f9cfcfeddd63e656d4010c98521af26c/node_modules/vitest/dist/chunks/index.DdgEv5B1.js +0 -46
- package/bundle/dist/node_modules/.pnpm/vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_ms_f9cfcfeddd63e656d4010c98521af26c/node_modules/vitest/dist/chunks/rpc.MzXet3jl.js +0 -119
- package/bundle/dist/node_modules/.pnpm/vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_ms_f9cfcfeddd63e656d4010c98521af26c/node_modules/vitest/dist/chunks/test.DNmyFkvJ.js +0 -3044
- package/bundle/dist/node_modules/.pnpm/vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_ms_f9cfcfeddd63e656d4010c98521af26c/node_modules/vitest/dist/chunks/utils.BX5Fg8C4.js +0 -59
- package/bundle/dist/node_modules/.pnpm/vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_ms_f9cfcfeddd63e656d4010c98521af26c/node_modules/vitest/dist/index.js +0 -28
- package/bundle/dist/utils/providers/openai/codex-rpc.js +0 -153
- package/bundle/dist/utils/providers/openai/codex-worker.js +0 -642
- package/bundle/dist/utils/providers/openai/openai-worker-pool-config.js +0 -51
- package/bundle/src/codex-protocol/AbsolutePathBuf.ts +0 -14
- package/bundle/src/codex-protocol/AgentPath.ts +0 -5
- package/bundle/src/codex-protocol/ApplyPatchApprovalParams.ts +0 -24
- package/bundle/src/codex-protocol/ApplyPatchApprovalResponse.ts +0 -6
- package/bundle/src/codex-protocol/AuthMode.ts +0 -8
- package/bundle/src/codex-protocol/ClientInfo.ts +0 -5
- package/bundle/src/codex-protocol/ClientNotification.ts +0 -5
- package/bundle/src/codex-protocol/ClientRequest.ts +0 -176
- package/bundle/src/codex-protocol/CollaborationMode.ts +0 -10
- package/bundle/src/codex-protocol/ContentItem.ts +0 -9
- package/bundle/src/codex-protocol/ConversationGitInfo.ts +0 -9
- package/bundle/src/codex-protocol/ConversationSummary.ts +0 -19
- package/bundle/src/codex-protocol/ExecCommandApprovalParams.ts +0 -22
- package/bundle/src/codex-protocol/ExecCommandApprovalResponse.ts +0 -6
- package/bundle/src/codex-protocol/ExecPolicyAmendment.ts +0 -12
- package/bundle/src/codex-protocol/FileChange.ts +0 -8
- package/bundle/src/codex-protocol/ForcedLoginMethod.ts +0 -5
- package/bundle/src/codex-protocol/FunctionCallOutputBody.ts +0 -6
- package/bundle/src/codex-protocol/FunctionCallOutputContentItem.ts +0 -12
- package/bundle/src/codex-protocol/FuzzyFileSearchMatchType.ts +0 -5
- package/bundle/src/codex-protocol/FuzzyFileSearchParams.ts +0 -9
- package/bundle/src/codex-protocol/FuzzyFileSearchResponse.ts +0 -6
- package/bundle/src/codex-protocol/FuzzyFileSearchResult.ts +0 -16
- package/bundle/src/codex-protocol/FuzzyFileSearchSessionCompletedNotification.ts +0 -5
- package/bundle/src/codex-protocol/FuzzyFileSearchSessionUpdatedNotification.ts +0 -10
- package/bundle/src/codex-protocol/GetAuthStatusParams.ts +0 -5
- package/bundle/src/codex-protocol/GetAuthStatusResponse.ts +0 -10
- package/bundle/src/codex-protocol/GetConversationSummaryParams.ts +0 -6
- package/bundle/src/codex-protocol/GetConversationSummaryResponse.ts +0 -6
- package/bundle/src/codex-protocol/GitDiffToRemoteParams.ts +0 -5
- package/bundle/src/codex-protocol/GitDiffToRemoteResponse.ts +0 -6
- package/bundle/src/codex-protocol/GitSha.ts +0 -5
- package/bundle/src/codex-protocol/ImageDetail.ts +0 -5
- package/bundle/src/codex-protocol/InitializeCapabilities.ts +0 -18
- package/bundle/src/codex-protocol/InitializeParams.ts +0 -10
- package/bundle/src/codex-protocol/InitializeResponse.ts +0 -22
- package/bundle/src/codex-protocol/InputModality.ts +0 -8
- package/bundle/src/codex-protocol/InternalSessionSource.ts +0 -5
- package/bundle/src/codex-protocol/LocalShellAction.ts +0 -6
- package/bundle/src/codex-protocol/LocalShellExecAction.ts +0 -11
- package/bundle/src/codex-protocol/LocalShellStatus.ts +0 -5
- package/bundle/src/codex-protocol/MessagePhase.ts +0 -11
- package/bundle/src/codex-protocol/ModeKind.ts +0 -8
- package/bundle/src/codex-protocol/NetworkPolicyAmendment.ts +0 -6
- package/bundle/src/codex-protocol/NetworkPolicyRuleAction.ts +0 -5
- package/bundle/src/codex-protocol/ParsedCommand.ts +0 -20
- package/bundle/src/codex-protocol/Personality.ts +0 -5
- package/bundle/src/codex-protocol/PlanType.ts +0 -17
- package/bundle/src/codex-protocol/RealtimeConversationVersion.ts +0 -5
- package/bundle/src/codex-protocol/RealtimeOutputModality.ts +0 -5
- package/bundle/src/codex-protocol/RealtimeVoice.ts +0 -24
- package/bundle/src/codex-protocol/RealtimeVoicesList.ts +0 -11
- package/bundle/src/codex-protocol/ReasoningEffort.ts +0 -8
- package/bundle/src/codex-protocol/ReasoningItemContent.ts +0 -7
- package/bundle/src/codex-protocol/ReasoningItemReasoningSummary.ts +0 -5
- package/bundle/src/codex-protocol/ReasoningSummary.ts +0 -10
- package/bundle/src/codex-protocol/RequestId.ts +0 -5
- package/bundle/src/codex-protocol/Resource.ts +0 -19
- package/bundle/src/codex-protocol/ResourceContent.ts +0 -27
- package/bundle/src/codex-protocol/ResourceTemplate.ts +0 -16
- package/bundle/src/codex-protocol/ResponseItem.ts +0 -63
- package/bundle/src/codex-protocol/ReviewDecision.ts +0 -17
- package/bundle/src/codex-protocol/ServerNotification.ts +0 -154
- package/bundle/src/codex-protocol/ServerRequest.ts +0 -47
- package/bundle/src/codex-protocol/SessionSource.ts +0 -15
- package/bundle/src/codex-protocol/Settings.ts +0 -13
- package/bundle/src/codex-protocol/SubAgentSource.ts +0 -20
- package/bundle/src/codex-protocol/ThreadId.ts +0 -5
- package/bundle/src/codex-protocol/ThreadMemoryMode.ts +0 -5
- package/bundle/src/codex-protocol/Tool.ts +0 -18
- package/bundle/src/codex-protocol/Verbosity.ts +0 -9
- package/bundle/src/codex-protocol/WebSearchAction.ts +0 -9
- package/bundle/src/codex-protocol/WebSearchContextSize.ts +0 -5
- package/bundle/src/codex-protocol/WebSearchLocation.ts +0 -10
- package/bundle/src/codex-protocol/WebSearchMode.ts +0 -5
- package/bundle/src/codex-protocol/WebSearchToolConfig.ts +0 -11
- package/bundle/src/codex-protocol/index.ts +0 -79
- package/bundle/src/codex-protocol/serde_json/JsonValue.ts +0 -11
- package/bundle/src/codex-protocol/v2/Account.ts +0 -9
- package/bundle/src/codex-protocol/v2/AccountLoginCompletedNotification.ts +0 -9
- package/bundle/src/codex-protocol/v2/AccountRateLimitsUpdatedNotification.ts +0 -6
- package/bundle/src/codex-protocol/v2/AccountUpdatedNotification.ts +0 -7
- package/bundle/src/codex-protocol/v2/ActivePermissionProfile.ts +0 -22
- package/bundle/src/codex-protocol/v2/ActivePermissionProfileModification.ts +0 -9
- package/bundle/src/codex-protocol/v2/AddCreditsNudgeCreditType.ts +0 -5
- package/bundle/src/codex-protocol/v2/AddCreditsNudgeEmailStatus.ts +0 -5
- package/bundle/src/codex-protocol/v2/AdditionalFileSystemPermissions.ts +0 -18
- package/bundle/src/codex-protocol/v2/AdditionalNetworkPermissions.ts +0 -5
- package/bundle/src/codex-protocol/v2/AdditionalPermissionProfile.ts +0 -13
- package/bundle/src/codex-protocol/v2/AgentMessageDeltaNotification.ts +0 -10
- package/bundle/src/codex-protocol/v2/AnalyticsConfig.ts +0 -14
- package/bundle/src/codex-protocol/v2/AppBranding.ts +0 -15
- package/bundle/src/codex-protocol/v2/AppInfo.ts +0 -32
- package/bundle/src/codex-protocol/v2/AppListUpdatedNotification.ts +0 -9
- package/bundle/src/codex-protocol/v2/AppMetadata.ts +0 -20
- package/bundle/src/codex-protocol/v2/AppReview.ts +0 -5
- package/bundle/src/codex-protocol/v2/AppScreenshot.ts +0 -5
- package/bundle/src/codex-protocol/v2/AppSummary.ts +0 -14
- package/bundle/src/codex-protocol/v2/AppToolApproval.ts +0 -5
- package/bundle/src/codex-protocol/v2/AppToolsConfig.ts +0 -8
- package/bundle/src/codex-protocol/v2/ApprovalsReviewer.ts +0 -12
- package/bundle/src/codex-protocol/v2/AppsConfig.ts +0 -17
- package/bundle/src/codex-protocol/v2/AppsDefaultConfig.ts +0 -9
- package/bundle/src/codex-protocol/v2/AppsListParams.ts +0 -25
- package/bundle/src/codex-protocol/v2/AppsListResponse.ts +0 -16
- package/bundle/src/codex-protocol/v2/AskForApproval.ts +0 -18
- package/bundle/src/codex-protocol/v2/AutoReviewDecisionSource.ts +0 -8
- package/bundle/src/codex-protocol/v2/ByteRange.ts +0 -5
- package/bundle/src/codex-protocol/v2/CancelLoginAccountParams.ts +0 -5
- package/bundle/src/codex-protocol/v2/CancelLoginAccountResponse.ts +0 -6
- package/bundle/src/codex-protocol/v2/CancelLoginAccountStatus.ts +0 -5
- package/bundle/src/codex-protocol/v2/ChatgptAuthTokensRefreshParams.ts +0 -18
- package/bundle/src/codex-protocol/v2/ChatgptAuthTokensRefreshReason.ts +0 -5
- package/bundle/src/codex-protocol/v2/ChatgptAuthTokensRefreshResponse.ts +0 -9
- package/bundle/src/codex-protocol/v2/CodexErrorInfo.ts +0 -27
- package/bundle/src/codex-protocol/v2/CollabAgentState.ts +0 -6
- package/bundle/src/codex-protocol/v2/CollabAgentStatus.ts +0 -12
- package/bundle/src/codex-protocol/v2/CollabAgentTool.ts +0 -5
- package/bundle/src/codex-protocol/v2/CollabAgentToolCallStatus.ts +0 -5
- package/bundle/src/codex-protocol/v2/CollaborationModeMask.ts +0 -15
- package/bundle/src/codex-protocol/v2/CommandAction.ts +0 -10
- package/bundle/src/codex-protocol/v2/CommandExecOutputDeltaNotification.ts +0 -31
- package/bundle/src/codex-protocol/v2/CommandExecOutputStream.ts +0 -8
- package/bundle/src/codex-protocol/v2/CommandExecParams.ts +0 -87
- package/bundle/src/codex-protocol/v2/CommandExecResizeParams.ts +0 -19
- package/bundle/src/codex-protocol/v2/CommandExecResizeResponse.ts +0 -8
- package/bundle/src/codex-protocol/v2/CommandExecResponse.ts +0 -25
- package/bundle/src/codex-protocol/v2/CommandExecTerminalSize.ts +0 -17
- package/bundle/src/codex-protocol/v2/CommandExecTerminateParams.ts +0 -14
- package/bundle/src/codex-protocol/v2/CommandExecTerminateResponse.ts +0 -8
- package/bundle/src/codex-protocol/v2/CommandExecWriteParams.ts +0 -23
- package/bundle/src/codex-protocol/v2/CommandExecWriteResponse.ts +0 -8
- package/bundle/src/codex-protocol/v2/CommandExecutionApprovalDecision.ts +0 -13
- package/bundle/src/codex-protocol/v2/CommandExecutionOutputDeltaNotification.ts +0 -10
- package/bundle/src/codex-protocol/v2/CommandExecutionRequestApprovalParams.ts +0 -47
- package/bundle/src/codex-protocol/v2/CommandExecutionRequestApprovalResponse.ts +0 -8
- package/bundle/src/codex-protocol/v2/CommandExecutionSource.ts +0 -9
- package/bundle/src/codex-protocol/v2/CommandExecutionStatus.ts +0 -5
- package/bundle/src/codex-protocol/v2/CommandMigration.ts +0 -5
- package/bundle/src/codex-protocol/v2/Config.ts +0 -53
- package/bundle/src/codex-protocol/v2/ConfigBatchWriteParams.ts +0 -17
- package/bundle/src/codex-protocol/v2/ConfigEdit.ts +0 -7
- package/bundle/src/codex-protocol/v2/ConfigLayer.ts +0 -12
- package/bundle/src/codex-protocol/v2/ConfigLayerMetadata.ts +0 -6
- package/bundle/src/codex-protocol/v2/ConfigLayerSource.ts +0 -27
- package/bundle/src/codex-protocol/v2/ConfigReadParams.ts +0 -13
- package/bundle/src/codex-protocol/v2/ConfigReadResponse.ts +0 -12
- package/bundle/src/codex-protocol/v2/ConfigRequirements.ts +0 -15
- package/bundle/src/codex-protocol/v2/ConfigRequirementsReadResponse.ts +0 -11
- package/bundle/src/codex-protocol/v2/ConfigValueWriteParams.ts +0 -16
- package/bundle/src/codex-protocol/v2/ConfigWarningNotification.ts +0 -23
- package/bundle/src/codex-protocol/v2/ConfigWriteResponse.ts +0 -16
- package/bundle/src/codex-protocol/v2/ConfiguredHookHandler.ts +0 -14
- package/bundle/src/codex-protocol/v2/ConfiguredHookMatcherGroup.ts +0 -9
- package/bundle/src/codex-protocol/v2/ContextCompactedNotification.ts +0 -8
- package/bundle/src/codex-protocol/v2/CreditsSnapshot.ts +0 -5
- package/bundle/src/codex-protocol/v2/DeprecationNoticeNotification.ts +0 -14
- package/bundle/src/codex-protocol/v2/DynamicToolCallOutputContentItem.ts +0 -7
- package/bundle/src/codex-protocol/v2/DynamicToolCallParams.ts +0 -13
- package/bundle/src/codex-protocol/v2/DynamicToolCallResponse.ts +0 -9
- package/bundle/src/codex-protocol/v2/DynamicToolCallStatus.ts +0 -5
- package/bundle/src/codex-protocol/v2/DynamicToolSpec.ts +0 -12
- package/bundle/src/codex-protocol/v2/ErrorNotification.ts +0 -11
- package/bundle/src/codex-protocol/v2/ExecPolicyAmendment.ts +0 -5
- package/bundle/src/codex-protocol/v2/ExperimentalFeature.ts +0 -38
- package/bundle/src/codex-protocol/v2/ExperimentalFeatureEnablementSetParams.ts +0 -13
- package/bundle/src/codex-protocol/v2/ExperimentalFeatureEnablementSetResponse.ts +0 -10
- package/bundle/src/codex-protocol/v2/ExperimentalFeatureListParams.ts +0 -14
- package/bundle/src/codex-protocol/v2/ExperimentalFeatureListResponse.ts +0 -13
- package/bundle/src/codex-protocol/v2/ExperimentalFeatureStage.ts +0 -10
- package/bundle/src/codex-protocol/v2/ExternalAgentConfigDetectParams.ts +0 -14
- package/bundle/src/codex-protocol/v2/ExternalAgentConfigDetectResponse.ts +0 -6
- package/bundle/src/codex-protocol/v2/ExternalAgentConfigImportCompletedNotification.ts +0 -5
- package/bundle/src/codex-protocol/v2/ExternalAgentConfigImportParams.ts +0 -8
- package/bundle/src/codex-protocol/v2/ExternalAgentConfigImportResponse.ts +0 -5
- package/bundle/src/codex-protocol/v2/ExternalAgentConfigMigrationItem.ts +0 -15
- package/bundle/src/codex-protocol/v2/ExternalAgentConfigMigrationItemType.ts +0 -14
- package/bundle/src/codex-protocol/v2/FeedbackUploadParams.ts +0 -12
- package/bundle/src/codex-protocol/v2/FeedbackUploadResponse.ts +0 -5
- package/bundle/src/codex-protocol/v2/FileChangeApprovalDecision.ts +0 -5
- package/bundle/src/codex-protocol/v2/FileChangeOutputDeltaNotification.ts +0 -15
- package/bundle/src/codex-protocol/v2/FileChangePatchUpdatedNotification.ts +0 -11
- package/bundle/src/codex-protocol/v2/FileChangeRequestApprovalParams.ts +0 -22
- package/bundle/src/codex-protocol/v2/FileChangeRequestApprovalResponse.ts +0 -6
- package/bundle/src/codex-protocol/v2/FileSystemAccessMode.ts +0 -5
- package/bundle/src/codex-protocol/v2/FileSystemPath.ts +0 -10
- package/bundle/src/codex-protocol/v2/FileSystemSandboxEntry.ts +0 -7
- package/bundle/src/codex-protocol/v2/FileSystemSpecialPath.ts +0 -11
- package/bundle/src/codex-protocol/v2/FileUpdateChange.ts +0 -6
- package/bundle/src/codex-protocol/v2/FsChangedNotification.ts +0 -18
- package/bundle/src/codex-protocol/v2/FsCopyParams.ts +0 -22
- package/bundle/src/codex-protocol/v2/FsCopyResponse.ts +0 -8
- package/bundle/src/codex-protocol/v2/FsCreateDirectoryParams.ts +0 -18
- package/bundle/src/codex-protocol/v2/FsCreateDirectoryResponse.ts +0 -8
- package/bundle/src/codex-protocol/v2/FsGetMetadataParams.ts +0 -14
- package/bundle/src/codex-protocol/v2/FsGetMetadataResponse.ts +0 -29
- package/bundle/src/codex-protocol/v2/FsReadDirectoryEntry.ts +0 -21
- package/bundle/src/codex-protocol/v2/FsReadDirectoryParams.ts +0 -14
- package/bundle/src/codex-protocol/v2/FsReadDirectoryResponse.ts +0 -14
- package/bundle/src/codex-protocol/v2/FsReadFileParams.ts +0 -14
- package/bundle/src/codex-protocol/v2/FsReadFileResponse.ts +0 -13
- package/bundle/src/codex-protocol/v2/FsRemoveParams.ts +0 -22
- package/bundle/src/codex-protocol/v2/FsRemoveResponse.ts +0 -8
- package/bundle/src/codex-protocol/v2/FsUnwatchParams.ts +0 -13
- package/bundle/src/codex-protocol/v2/FsUnwatchResponse.ts +0 -8
- package/bundle/src/codex-protocol/v2/FsWatchParams.ts +0 -18
- package/bundle/src/codex-protocol/v2/FsWatchResponse.ts +0 -14
- package/bundle/src/codex-protocol/v2/FsWriteFileParams.ts +0 -18
- package/bundle/src/codex-protocol/v2/FsWriteFileResponse.ts +0 -8
- package/bundle/src/codex-protocol/v2/GetAccountParams.ts +0 -14
- package/bundle/src/codex-protocol/v2/GetAccountRateLimitsResponse.ts +0 -15
- package/bundle/src/codex-protocol/v2/GetAccountResponse.ts +0 -6
- package/bundle/src/codex-protocol/v2/GitInfo.ts +0 -5
- package/bundle/src/codex-protocol/v2/GrantedPermissionProfile.ts +0 -10
- package/bundle/src/codex-protocol/v2/GuardianApprovalReview.ts +0 -18
- package/bundle/src/codex-protocol/v2/GuardianApprovalReviewAction.ts +0 -34
- package/bundle/src/codex-protocol/v2/GuardianApprovalReviewStatus.ts +0 -13
- package/bundle/src/codex-protocol/v2/GuardianCommandSource.ts +0 -5
- package/bundle/src/codex-protocol/v2/GuardianRiskLevel.ts +0 -8
- package/bundle/src/codex-protocol/v2/GuardianUserAuthorization.ts +0 -8
- package/bundle/src/codex-protocol/v2/GuardianWarningNotification.ts +0 -14
- package/bundle/src/codex-protocol/v2/HookCompletedNotification.ts +0 -10
- package/bundle/src/codex-protocol/v2/HookErrorInfo.ts +0 -5
- package/bundle/src/codex-protocol/v2/HookEventName.ts +0 -13
- package/bundle/src/codex-protocol/v2/HookExecutionMode.ts +0 -5
- package/bundle/src/codex-protocol/v2/HookHandlerType.ts +0 -5
- package/bundle/src/codex-protocol/v2/HookMetadata.ts +0 -26
- package/bundle/src/codex-protocol/v2/HookMigration.ts +0 -5
- package/bundle/src/codex-protocol/v2/HookOutputEntry.ts +0 -6
- package/bundle/src/codex-protocol/v2/HookOutputEntryKind.ts +0 -5
- package/bundle/src/codex-protocol/v2/HookPromptFragment.ts +0 -5
- package/bundle/src/codex-protocol/v2/HookRunStatus.ts +0 -5
- package/bundle/src/codex-protocol/v2/HookRunSummary.ts +0 -28
- package/bundle/src/codex-protocol/v2/HookScope.ts +0 -5
- package/bundle/src/codex-protocol/v2/HookSource.ts +0 -15
- package/bundle/src/codex-protocol/v2/HookStartedNotification.ts +0 -10
- package/bundle/src/codex-protocol/v2/HookTrustStatus.ts +0 -5
- package/bundle/src/codex-protocol/v2/HooksListEntry.ts +0 -12
- package/bundle/src/codex-protocol/v2/HooksListParams.ts +0 -10
- package/bundle/src/codex-protocol/v2/HooksListResponse.ts +0 -6
- package/bundle/src/codex-protocol/v2/ItemCompletedNotification.ts +0 -14
- package/bundle/src/codex-protocol/v2/ItemGuardianApprovalReviewCompletedNotification.ts +0 -44
- package/bundle/src/codex-protocol/v2/ItemGuardianApprovalReviewStartedNotification.ts +0 -38
- package/bundle/src/codex-protocol/v2/ItemStartedNotification.ts +0 -14
- package/bundle/src/codex-protocol/v2/ListMcpServerStatusParams.ts +0 -20
- package/bundle/src/codex-protocol/v2/ListMcpServerStatusResponse.ts +0 -13
- package/bundle/src/codex-protocol/v2/LoginAccountParams.ts +0 -27
- package/bundle/src/codex-protocol/v2/LoginAccountResponse.ts +0 -27
- package/bundle/src/codex-protocol/v2/LogoutAccountResponse.ts +0 -5
- package/bundle/src/codex-protocol/v2/ManagedHooksRequirements.ts +0 -17
- package/bundle/src/codex-protocol/v2/MarketplaceAddParams.ts +0 -9
- package/bundle/src/codex-protocol/v2/MarketplaceAddResponse.ts +0 -10
- package/bundle/src/codex-protocol/v2/MarketplaceInterface.ts +0 -5
- package/bundle/src/codex-protocol/v2/MarketplaceLoadErrorInfo.ts +0 -6
- package/bundle/src/codex-protocol/v2/MarketplaceRemoveParams.ts +0 -5
- package/bundle/src/codex-protocol/v2/MarketplaceRemoveResponse.ts +0 -9
- package/bundle/src/codex-protocol/v2/MarketplaceUpgradeErrorInfo.ts +0 -5
- package/bundle/src/codex-protocol/v2/MarketplaceUpgradeParams.ts +0 -5
- package/bundle/src/codex-protocol/v2/MarketplaceUpgradeResponse.ts +0 -11
- package/bundle/src/codex-protocol/v2/McpAuthStatus.ts +0 -5
- package/bundle/src/codex-protocol/v2/McpElicitationArrayType.ts +0 -5
- package/bundle/src/codex-protocol/v2/McpElicitationBooleanSchema.ts +0 -11
- package/bundle/src/codex-protocol/v2/McpElicitationBooleanType.ts +0 -5
- package/bundle/src/codex-protocol/v2/McpElicitationConstOption.ts +0 -5
- package/bundle/src/codex-protocol/v2/McpElicitationEnumSchema.ts +0 -11
- package/bundle/src/codex-protocol/v2/McpElicitationLegacyTitledEnumSchema.ts +0 -13
- package/bundle/src/codex-protocol/v2/McpElicitationMultiSelectEnumSchema.ts +0 -9
- package/bundle/src/codex-protocol/v2/McpElicitationNumberSchema.ts +0 -13
- package/bundle/src/codex-protocol/v2/McpElicitationNumberType.ts +0 -5
- package/bundle/src/codex-protocol/v2/McpElicitationObjectType.ts +0 -5
- package/bundle/src/codex-protocol/v2/McpElicitationPrimitiveSchema.ts +0 -13
- package/bundle/src/codex-protocol/v2/McpElicitationSchema.ts +0 -18
- package/bundle/src/codex-protocol/v2/McpElicitationSingleSelectEnumSchema.ts +0 -9
- package/bundle/src/codex-protocol/v2/McpElicitationStringFormat.ts +0 -5
- package/bundle/src/codex-protocol/v2/McpElicitationStringSchema.ts +0 -15
- package/bundle/src/codex-protocol/v2/McpElicitationStringType.ts +0 -5
- package/bundle/src/codex-protocol/v2/McpElicitationTitledEnumItems.ts +0 -6
- package/bundle/src/codex-protocol/v2/McpElicitationTitledMultiSelectEnumSchema.ts +0 -15
- package/bundle/src/codex-protocol/v2/McpElicitationTitledSingleSelectEnumSchema.ts +0 -13
- package/bundle/src/codex-protocol/v2/McpElicitationUntitledEnumItems.ts +0 -9
- package/bundle/src/codex-protocol/v2/McpElicitationUntitledMultiSelectEnumSchema.ts +0 -15
- package/bundle/src/codex-protocol/v2/McpElicitationUntitledSingleSelectEnumSchema.ts +0 -12
- package/bundle/src/codex-protocol/v2/McpResourceReadParams.ts +0 -5
- package/bundle/src/codex-protocol/v2/McpResourceReadResponse.ts +0 -6
- package/bundle/src/codex-protocol/v2/McpServerElicitationAction.ts +0 -5
- package/bundle/src/codex-protocol/v2/McpServerElicitationRequestParams.ts +0 -27
- package/bundle/src/codex-protocol/v2/McpServerElicitationRequestResponse.ts +0 -19
- package/bundle/src/codex-protocol/v2/McpServerMigration.ts +0 -5
- package/bundle/src/codex-protocol/v2/McpServerOauthLoginCompletedNotification.ts +0 -9
- package/bundle/src/codex-protocol/v2/McpServerOauthLoginParams.ts +0 -9
- package/bundle/src/codex-protocol/v2/McpServerOauthLoginResponse.ts +0 -5
- package/bundle/src/codex-protocol/v2/McpServerRefreshResponse.ts +0 -5
- package/bundle/src/codex-protocol/v2/McpServerStartupState.ts +0 -5
- package/bundle/src/codex-protocol/v2/McpServerStatus.ts +0 -15
- package/bundle/src/codex-protocol/v2/McpServerStatusDetail.ts +0 -5
- package/bundle/src/codex-protocol/v2/McpServerStatusUpdatedNotification.ts +0 -10
- package/bundle/src/codex-protocol/v2/McpServerToolCallParams.ts +0 -12
- package/bundle/src/codex-protocol/v2/McpServerToolCallResponse.ts +0 -11
- package/bundle/src/codex-protocol/v2/McpToolCallError.ts +0 -5
- package/bundle/src/codex-protocol/v2/McpToolCallProgressNotification.ts +0 -10
- package/bundle/src/codex-protocol/v2/McpToolCallResult.ts +0 -10
- package/bundle/src/codex-protocol/v2/McpToolCallStatus.ts +0 -5
- package/bundle/src/codex-protocol/v2/MemoryCitation.ts +0 -6
- package/bundle/src/codex-protocol/v2/MemoryCitationEntry.ts +0 -10
- package/bundle/src/codex-protocol/v2/MergeStrategy.ts +0 -5
- package/bundle/src/codex-protocol/v2/MigrationDetails.ts +0 -18
- package/bundle/src/codex-protocol/v2/Model.ts +0 -30
- package/bundle/src/codex-protocol/v2/ModelAvailabilityNux.ts +0 -5
- package/bundle/src/codex-protocol/v2/ModelListParams.ts +0 -18
- package/bundle/src/codex-protocol/v2/ModelListResponse.ts +0 -13
- package/bundle/src/codex-protocol/v2/ModelProviderCapabilitiesReadParams.ts +0 -5
- package/bundle/src/codex-protocol/v2/ModelProviderCapabilitiesReadResponse.ts +0 -9
- package/bundle/src/codex-protocol/v2/ModelRerouteReason.ts +0 -5
- package/bundle/src/codex-protocol/v2/ModelReroutedNotification.ts +0 -12
- package/bundle/src/codex-protocol/v2/ModelServiceTier.ts +0 -5
- package/bundle/src/codex-protocol/v2/ModelUpgradeInfo.ts +0 -10
- package/bundle/src/codex-protocol/v2/ModelVerification.ts +0 -5
- package/bundle/src/codex-protocol/v2/ModelVerificationNotification.ts +0 -10
- package/bundle/src/codex-protocol/v2/NetworkAccess.ts +0 -5
- package/bundle/src/codex-protocol/v2/NetworkApprovalContext.ts +0 -6
- package/bundle/src/codex-protocol/v2/NetworkApprovalProtocol.ts +0 -5
- package/bundle/src/codex-protocol/v2/NetworkDomainPermission.ts +0 -5
- package/bundle/src/codex-protocol/v2/NetworkPolicyAmendment.ts +0 -6
- package/bundle/src/codex-protocol/v2/NetworkPolicyRuleAction.ts +0 -5
- package/bundle/src/codex-protocol/v2/NetworkRequirements.ts +0 -40
- package/bundle/src/codex-protocol/v2/NetworkUnixSocketPermission.ts +0 -5
- package/bundle/src/codex-protocol/v2/NonSteerableTurnKind.ts +0 -5
- package/bundle/src/codex-protocol/v2/OverriddenMetadata.ts +0 -11
- package/bundle/src/codex-protocol/v2/PatchApplyStatus.ts +0 -5
- package/bundle/src/codex-protocol/v2/PatchChangeKind.ts +0 -8
- package/bundle/src/codex-protocol/v2/PermissionGrantScope.ts +0 -5
- package/bundle/src/codex-protocol/v2/PermissionProfile.ts +0 -14
- package/bundle/src/codex-protocol/v2/PermissionProfileFileSystemPermissions.ts +0 -8
- package/bundle/src/codex-protocol/v2/PermissionProfileModificationParams.ts +0 -9
- package/bundle/src/codex-protocol/v2/PermissionProfileNetworkPermissions.ts +0 -5
- package/bundle/src/codex-protocol/v2/PermissionProfileSelectionParams.ts +0 -10
- package/bundle/src/codex-protocol/v2/PermissionsRequestApprovalParams.ts +0 -18
- package/bundle/src/codex-protocol/v2/PermissionsRequestApprovalResponse.ts +0 -14
- package/bundle/src/codex-protocol/v2/PlanDeltaNotification.ts +0 -14
- package/bundle/src/codex-protocol/v2/PluginAuthPolicy.ts +0 -5
- package/bundle/src/codex-protocol/v2/PluginAvailability.ts +0 -5
- package/bundle/src/codex-protocol/v2/PluginDetail.ts +0 -19
- package/bundle/src/codex-protocol/v2/PluginHookSummary.ts +0 -6
- package/bundle/src/codex-protocol/v2/PluginInstallParams.ts +0 -10
- package/bundle/src/codex-protocol/v2/PluginInstallPolicy.ts +0 -5
- package/bundle/src/codex-protocol/v2/PluginInstallResponse.ts +0 -10
- package/bundle/src/codex-protocol/v2/PluginInterface.ts +0 -46
- package/bundle/src/codex-protocol/v2/PluginListMarketplaceKind.ts +0 -5
- package/bundle/src/codex-protocol/v2/PluginListParams.ts +0 -18
- package/bundle/src/codex-protocol/v2/PluginListResponse.ts +0 -11
- package/bundle/src/codex-protocol/v2/PluginMarketplaceEntry.ts +0 -17
- package/bundle/src/codex-protocol/v2/PluginReadParams.ts +0 -10
- package/bundle/src/codex-protocol/v2/PluginReadResponse.ts +0 -6
- package/bundle/src/codex-protocol/v2/PluginShareContext.ts +0 -12
- package/bundle/src/codex-protocol/v2/PluginShareDeleteParams.ts +0 -5
- package/bundle/src/codex-protocol/v2/PluginShareDeleteResponse.ts +0 -5
- package/bundle/src/codex-protocol/v2/PluginShareDiscoverability.ts +0 -5
- package/bundle/src/codex-protocol/v2/PluginShareListItem.ts +0 -11
- package/bundle/src/codex-protocol/v2/PluginShareListParams.ts +0 -5
- package/bundle/src/codex-protocol/v2/PluginShareListResponse.ts +0 -6
- package/bundle/src/codex-protocol/v2/PluginSharePrincipal.ts +0 -10
- package/bundle/src/codex-protocol/v2/PluginSharePrincipalType.ts +0 -5
- package/bundle/src/codex-protocol/v2/PluginShareSaveParams.ts +0 -13
- package/bundle/src/codex-protocol/v2/PluginShareSaveResponse.ts +0 -5
- package/bundle/src/codex-protocol/v2/PluginShareTarget.ts +0 -6
- package/bundle/src/codex-protocol/v2/PluginShareUpdateDiscoverability.ts +0 -5
- package/bundle/src/codex-protocol/v2/PluginShareUpdateTargetsParams.ts +0 -11
- package/bundle/src/codex-protocol/v2/PluginShareUpdateTargetsResponse.ts +0 -10
- package/bundle/src/codex-protocol/v2/PluginSkillReadParams.ts +0 -9
- package/bundle/src/codex-protocol/v2/PluginSkillReadResponse.ts +0 -5
- package/bundle/src/codex-protocol/v2/PluginSource.ts +0 -9
- package/bundle/src/codex-protocol/v2/PluginSummary.ts +0 -29
- package/bundle/src/codex-protocol/v2/PluginUninstallParams.ts +0 -5
- package/bundle/src/codex-protocol/v2/PluginUninstallResponse.ts +0 -5
- package/bundle/src/codex-protocol/v2/PluginsMigration.ts +0 -5
- package/bundle/src/codex-protocol/v2/ProcessExitedNotification.ts +0 -43
- package/bundle/src/codex-protocol/v2/ProcessOutputDeltaNotification.ts +0 -27
- package/bundle/src/codex-protocol/v2/ProcessOutputStream.ts +0 -8
- package/bundle/src/codex-protocol/v2/ProcessTerminalSize.ts +0 -17
- package/bundle/src/codex-protocol/v2/ProfileV2.ts +0 -37
- package/bundle/src/codex-protocol/v2/RateLimitReachedType.ts +0 -10
- package/bundle/src/codex-protocol/v2/RateLimitSnapshot.ts +0 -17
- package/bundle/src/codex-protocol/v2/RateLimitWindow.ts +0 -9
- package/bundle/src/codex-protocol/v2/RawResponseItemCompletedNotification.ts +0 -10
- package/bundle/src/codex-protocol/v2/ReasoningEffortOption.ts +0 -6
- package/bundle/src/codex-protocol/v2/ReasoningSummaryPartAddedNotification.ts +0 -10
- package/bundle/src/codex-protocol/v2/ReasoningSummaryTextDeltaNotification.ts +0 -11
- package/bundle/src/codex-protocol/v2/ReasoningTextDeltaNotification.ts +0 -11
- package/bundle/src/codex-protocol/v2/RemoteControlConnectionStatus.ts +0 -5
- package/bundle/src/codex-protocol/v2/RemoteControlStatusChangedNotification.ts +0 -12
- package/bundle/src/codex-protocol/v2/RequestPermissionProfile.ts +0 -10
- package/bundle/src/codex-protocol/v2/ResidencyRequirement.ts +0 -5
- package/bundle/src/codex-protocol/v2/ReviewDelivery.ts +0 -5
- package/bundle/src/codex-protocol/v2/ReviewStartParams.ts +0 -15
- package/bundle/src/codex-protocol/v2/ReviewStartResponse.ts +0 -15
- package/bundle/src/codex-protocol/v2/ReviewTarget.ts +0 -16
- package/bundle/src/codex-protocol/v2/SandboxMode.ts +0 -5
- package/bundle/src/codex-protocol/v2/SandboxPolicy.ts +0 -17
- package/bundle/src/codex-protocol/v2/SandboxWorkspaceWrite.ts +0 -10
- package/bundle/src/codex-protocol/v2/SendAddCreditsNudgeEmailParams.ts +0 -6
- package/bundle/src/codex-protocol/v2/SendAddCreditsNudgeEmailResponse.ts +0 -6
- package/bundle/src/codex-protocol/v2/ServerRequestResolvedNotification.ts +0 -6
- package/bundle/src/codex-protocol/v2/SessionMigration.ts +0 -5
- package/bundle/src/codex-protocol/v2/SessionSource.ts +0 -13
- package/bundle/src/codex-protocol/v2/SkillDependencies.ts +0 -6
- package/bundle/src/codex-protocol/v2/SkillErrorInfo.ts +0 -5
- package/bundle/src/codex-protocol/v2/SkillInterface.ts +0 -13
- package/bundle/src/codex-protocol/v2/SkillMetadata.ts +0 -21
- package/bundle/src/codex-protocol/v2/SkillScope.ts +0 -5
- package/bundle/src/codex-protocol/v2/SkillSummary.ts +0 -14
- package/bundle/src/codex-protocol/v2/SkillToolDependency.ts +0 -12
- package/bundle/src/codex-protocol/v2/SkillsChangedNotification.ts +0 -11
- package/bundle/src/codex-protocol/v2/SkillsConfigWriteParams.ts +0 -16
- package/bundle/src/codex-protocol/v2/SkillsConfigWriteResponse.ts +0 -5
- package/bundle/src/codex-protocol/v2/SkillsListEntry.ts +0 -11
- package/bundle/src/codex-protocol/v2/SkillsListParams.ts +0 -14
- package/bundle/src/codex-protocol/v2/SkillsListResponse.ts +0 -6
- package/bundle/src/codex-protocol/v2/SortDirection.ts +0 -5
- package/bundle/src/codex-protocol/v2/SubagentMigration.ts +0 -5
- package/bundle/src/codex-protocol/v2/TerminalInteractionNotification.ts +0 -11
- package/bundle/src/codex-protocol/v2/TextElement.ts +0 -15
- package/bundle/src/codex-protocol/v2/TextPosition.ts +0 -14
- package/bundle/src/codex-protocol/v2/TextRange.ts +0 -6
- package/bundle/src/codex-protocol/v2/Thread.ts +0 -88
- package/bundle/src/codex-protocol/v2/ThreadActiveFlag.ts +0 -5
- package/bundle/src/codex-protocol/v2/ThreadApproveGuardianDeniedActionParams.ts +0 -12
- package/bundle/src/codex-protocol/v2/ThreadApproveGuardianDeniedActionResponse.ts +0 -5
- package/bundle/src/codex-protocol/v2/ThreadArchiveParams.ts +0 -5
- package/bundle/src/codex-protocol/v2/ThreadArchiveResponse.ts +0 -5
- package/bundle/src/codex-protocol/v2/ThreadArchivedNotification.ts +0 -5
- package/bundle/src/codex-protocol/v2/ThreadClosedNotification.ts +0 -5
- package/bundle/src/codex-protocol/v2/ThreadCompactStartParams.ts +0 -5
- package/bundle/src/codex-protocol/v2/ThreadCompactStartResponse.ts +0 -5
- package/bundle/src/codex-protocol/v2/ThreadForkParams.ts +0 -40
- package/bundle/src/codex-protocol/v2/ThreadForkResponse.ts +0 -30
- package/bundle/src/codex-protocol/v2/ThreadGoal.ts +0 -15
- package/bundle/src/codex-protocol/v2/ThreadGoalClearedNotification.ts +0 -5
- package/bundle/src/codex-protocol/v2/ThreadGoalStatus.ts +0 -5
- package/bundle/src/codex-protocol/v2/ThreadGoalUpdatedNotification.ts +0 -10
- package/bundle/src/codex-protocol/v2/ThreadInjectItemsParams.ts +0 -12
- package/bundle/src/codex-protocol/v2/ThreadInjectItemsResponse.ts +0 -5
- package/bundle/src/codex-protocol/v2/ThreadItem.ts +0 -156
- package/bundle/src/codex-protocol/v2/ThreadListParams.ts +0 -55
- package/bundle/src/codex-protocol/v2/ThreadListResponse.ts +0 -20
- package/bundle/src/codex-protocol/v2/ThreadLoadedListParams.ts +0 -14
- package/bundle/src/codex-protocol/v2/ThreadLoadedListResponse.ts +0 -15
- package/bundle/src/codex-protocol/v2/ThreadMetadataGitInfoUpdateParams.ts +0 -21
- package/bundle/src/codex-protocol/v2/ThreadMetadataUpdateParams.ts +0 -14
- package/bundle/src/codex-protocol/v2/ThreadMetadataUpdateResponse.ts +0 -6
- package/bundle/src/codex-protocol/v2/ThreadNameUpdatedNotification.ts +0 -5
- package/bundle/src/codex-protocol/v2/ThreadReadParams.ts +0 -11
- package/bundle/src/codex-protocol/v2/ThreadReadResponse.ts +0 -6
- package/bundle/src/codex-protocol/v2/ThreadRealtimeAudioChunk.ts +0 -14
- package/bundle/src/codex-protocol/v2/ThreadRealtimeClosedNotification.ts +0 -8
- package/bundle/src/codex-protocol/v2/ThreadRealtimeErrorNotification.ts +0 -8
- package/bundle/src/codex-protocol/v2/ThreadRealtimeItemAddedNotification.ts +0 -9
- package/bundle/src/codex-protocol/v2/ThreadRealtimeOutputAudioDeltaNotification.ts +0 -12
- package/bundle/src/codex-protocol/v2/ThreadRealtimeSdpNotification.ts +0 -8
- package/bundle/src/codex-protocol/v2/ThreadRealtimeStartTransport.ts +0 -17
- package/bundle/src/codex-protocol/v2/ThreadRealtimeStartedNotification.ts +0 -13
- package/bundle/src/codex-protocol/v2/ThreadRealtimeTranscriptDeltaNotification.ts +0 -16
- package/bundle/src/codex-protocol/v2/ThreadRealtimeTranscriptDoneNotification.ts +0 -16
- package/bundle/src/codex-protocol/v2/ThreadResumeParams.ts +0 -39
- package/bundle/src/codex-protocol/v2/ThreadResumeResponse.ts +0 -30
- package/bundle/src/codex-protocol/v2/ThreadRollbackParams.ts +0 -14
- package/bundle/src/codex-protocol/v2/ThreadRollbackResponse.ts +0 -15
- package/bundle/src/codex-protocol/v2/ThreadSetNameParams.ts +0 -5
- package/bundle/src/codex-protocol/v2/ThreadSetNameResponse.ts +0 -5
- package/bundle/src/codex-protocol/v2/ThreadShellCommandParams.ts +0 -14
- package/bundle/src/codex-protocol/v2/ThreadShellCommandResponse.ts +0 -5
- package/bundle/src/codex-protocol/v2/ThreadSortKey.ts +0 -5
- package/bundle/src/codex-protocol/v2/ThreadSource.ts +0 -5
- package/bundle/src/codex-protocol/v2/ThreadSourceKind.ts +0 -15
- package/bundle/src/codex-protocol/v2/ThreadStartParams.ts +0 -33
- package/bundle/src/codex-protocol/v2/ThreadStartResponse.ts +0 -30
- package/bundle/src/codex-protocol/v2/ThreadStartSource.ts +0 -5
- package/bundle/src/codex-protocol/v2/ThreadStartedNotification.ts +0 -6
- package/bundle/src/codex-protocol/v2/ThreadStatus.ts +0 -10
- package/bundle/src/codex-protocol/v2/ThreadStatusChangedNotification.ts +0 -6
- package/bundle/src/codex-protocol/v2/ThreadTokenUsage.ts +0 -10
- package/bundle/src/codex-protocol/v2/ThreadTokenUsageUpdatedNotification.ts +0 -10
- package/bundle/src/codex-protocol/v2/ThreadUnarchiveParams.ts +0 -5
- package/bundle/src/codex-protocol/v2/ThreadUnarchiveResponse.ts +0 -6
- package/bundle/src/codex-protocol/v2/ThreadUnarchivedNotification.ts +0 -5
- package/bundle/src/codex-protocol/v2/ThreadUnsubscribeParams.ts +0 -5
- package/bundle/src/codex-protocol/v2/ThreadUnsubscribeResponse.ts +0 -6
- package/bundle/src/codex-protocol/v2/ThreadUnsubscribeStatus.ts +0 -5
- package/bundle/src/codex-protocol/v2/TokenUsageBreakdown.ts +0 -11
- package/bundle/src/codex-protocol/v2/ToolRequestUserInputAnswer.ts +0 -8
- package/bundle/src/codex-protocol/v2/ToolRequestUserInputOption.ts +0 -8
- package/bundle/src/codex-protocol/v2/ToolRequestUserInputParams.ts +0 -14
- package/bundle/src/codex-protocol/v2/ToolRequestUserInputQuestion.ts +0 -16
- package/bundle/src/codex-protocol/v2/ToolRequestUserInputResponse.ts +0 -11
- package/bundle/src/codex-protocol/v2/ToolsV2.ts +0 -6
- package/bundle/src/codex-protocol/v2/Turn.ts +0 -36
- package/bundle/src/codex-protocol/v2/TurnCompletedNotification.ts +0 -6
- package/bundle/src/codex-protocol/v2/TurnDiffUpdatedNotification.ts +0 -9
- package/bundle/src/codex-protocol/v2/TurnEnvironmentParams.ts +0 -6
- package/bundle/src/codex-protocol/v2/TurnError.ts +0 -10
- package/bundle/src/codex-protocol/v2/TurnInterruptParams.ts +0 -5
- package/bundle/src/codex-protocol/v2/TurnInterruptResponse.ts +0 -5
- package/bundle/src/codex-protocol/v2/TurnItemsView.ts +0 -5
- package/bundle/src/codex-protocol/v2/TurnPlanStep.ts +0 -6
- package/bundle/src/codex-protocol/v2/TurnPlanStepStatus.ts +0 -5
- package/bundle/src/codex-protocol/v2/TurnPlanUpdatedNotification.ts +0 -11
- package/bundle/src/codex-protocol/v2/TurnStartParams.ts +0 -48
- package/bundle/src/codex-protocol/v2/TurnStartResponse.ts +0 -6
- package/bundle/src/codex-protocol/v2/TurnStartedNotification.ts +0 -6
- package/bundle/src/codex-protocol/v2/TurnStatus.ts +0 -5
- package/bundle/src/codex-protocol/v2/TurnSteerParams.ts +0 -13
- package/bundle/src/codex-protocol/v2/TurnSteerResponse.ts +0 -5
- package/bundle/src/codex-protocol/v2/UserInput.ts +0 -18
- package/bundle/src/codex-protocol/v2/WarningNotification.ts +0 -14
- package/bundle/src/codex-protocol/v2/WebSearchAction.ts +0 -9
- package/bundle/src/codex-protocol/v2/WindowsSandboxReadiness.ts +0 -5
- package/bundle/src/codex-protocol/v2/WindowsSandboxReadinessResponse.ts +0 -6
- package/bundle/src/codex-protocol/v2/WindowsSandboxSetupCompletedNotification.ts +0 -10
- package/bundle/src/codex-protocol/v2/WindowsSandboxSetupMode.ts +0 -5
- package/bundle/src/codex-protocol/v2/WindowsSandboxSetupStartParams.ts +0 -10
- package/bundle/src/codex-protocol/v2/WindowsSandboxSetupStartResponse.ts +0 -5
- package/bundle/src/codex-protocol/v2/WindowsWorldWritableWarningNotification.ts +0 -9
- package/bundle/src/codex-protocol/v2/WriteStatus.ts +0 -5
- package/bundle/src/codex-protocol/v2/index.ts +0 -446
- package/bundle/src/utils/providers/openai/codex-rpc.ts +0 -238
- package/bundle/src/utils/providers/openai/codex-worker.test.ts +0 -1006
- package/bundle/src/utils/providers/openai/codex-worker.ts +0 -927
- package/bundle/src/utils/providers/openai/openai-worker-pool-config.ts +0 -112
- package/bundle/web-dist/client/assets/index-C24D5PiN.js +0 -106
- package/bundle/web-dist/client/assets/index-CcMEpCgt.css +0 -1
- package/bundle/web-dist/client/assets/logs-CIlZG6A3.js +0 -1
- package/bundle/web-dist/client/assets/monit-DZFBMxKl.js +0 -1
- package/bundle/web-dist/client/assets/routes-C3wlSNBL.js +0 -5
- package/bundle/web-dist/client/assets/services.generated-jGypfumC.js +0 -51
- package/bundle/web-dist/client/assets/settings-ClRDWO-8.js +0 -1
- package/bundle/web-dist/client/assets/show-BP7U8yyJ.js +0 -2
- package/bundle/web-dist/client/assets/tokens-DfQeULnJ.js +0 -1
- package/bundle/web-dist/client/assets/use-oauth-login-flow-CY-ASCfL.js +0 -1
- package/bundle/web-dist/server/assets/lazyRouteComponent-DOc8TV-P.js +0 -1856
- package/bundle/web-dist/server/assets/logs-CfF3nmLM.js +0 -451
- package/bundle/web-dist/server/assets/monit-BSaKhh5D.js +0 -1577
- package/bundle/web-dist/server/assets/plus-DLFUHsfx.js +0 -19
- package/bundle/web-dist/server/assets/react-dom-BotjLnTK.js +0 -462
- package/bundle/web-dist/server/assets/routes-CHMxrTT0.js +0 -2924
- package/bundle/web-dist/server/assets/services.generated-D3Q3FYot.js +0 -23570
- package/bundle/web-dist/server/assets/settings-DOQjV28c.js +0 -598
- package/bundle/web-dist/server/assets/show-Cn_C6Qvl.js +0 -2776
- package/bundle/web-dist/server/assets/tokens-c0EN3iCx.js +0 -441
- package/bundle/web-dist/server/assets/use-oauth-login-flow-B68AbMDE.js +0 -160
- /package/bundle/dist/{codex-protocol/AbsolutePathBuf.js → utils/providers/common/provider-types.js} +0 -0
|
@@ -1,23 +1,14 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { resolveOpenAITransportKind } from "./openai-transport-config.js";
|
|
2
2
|
import { QuotaThresholdExceededError } from "../../../application/qgrid/qgrid.types.js";
|
|
3
3
|
import { TokenModel } from "../../../application/token/token.model.js";
|
|
4
4
|
import { SmoothWeightedRoundRobin } from "../common/smooth-weighted-round-robin.js";
|
|
5
|
-
import {
|
|
5
|
+
import { OpenAIDirectClient } from "./openai-direct-client.js";
|
|
6
6
|
import { readOpenAIQuotaUsage } from "./openai-quota.js";
|
|
7
7
|
import { handleChatgptAuthTokensRefresh } from "./openai-refresh.js";
|
|
8
8
|
import { getLogger } from "@logtape/logtape";
|
|
9
|
-
import { readFileSync } from "node:fs";
|
|
10
|
-
import { freemem } from "node:os";
|
|
11
9
|
//#region src/utils/providers/openai/openai-dispatcher.ts
|
|
12
|
-
/**
|
|
13
|
-
* OpenAIDispatcher — codex app-server worker pool + 토큰 라우팅.
|
|
14
|
-
*
|
|
15
|
-
* - 토큰당 CodexAppServerWorker 자동 확장 (기본 1~3, hard cap 20)
|
|
16
|
-
* - idle worker round-robin 선택 + 큐 대기 (전부 busy 시)
|
|
17
|
-
* - TokenSubscriber 이벤트로 worker pool 동기화
|
|
18
|
-
* - backpressure: 큐 full 또는 timeout 시 SERVER_BUSY
|
|
19
|
-
*/
|
|
20
10
|
const logger = getLogger(["qgrid", "openai-dispatcher"]);
|
|
11
|
+
const DEFAULT_REQUEST_TIMEOUT_MS = 6e5;
|
|
21
12
|
var ImageGenerationError = class extends Error {
|
|
22
13
|
kind;
|
|
23
14
|
constructor(kind, message) {
|
|
@@ -26,839 +17,425 @@ var ImageGenerationError = class extends Error {
|
|
|
26
17
|
this.name = "ImageGenerationError";
|
|
27
18
|
}
|
|
28
19
|
};
|
|
29
|
-
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
const SPAWN_INTERVAL_MS = 500;
|
|
33
|
-
function readHostAvailableGiB() {
|
|
34
|
-
try {
|
|
35
|
-
const match = readFileSync("/proc/meminfo", "utf8").match(/^MemAvailable:\s+(\d+)\s+kB$/m);
|
|
36
|
-
if (match?.[1]) return Number(match[1]) / 1024 / 1024;
|
|
37
|
-
} catch {}
|
|
38
|
-
return freemem() / 1024 / 1024 / 1024;
|
|
20
|
+
function abortError(signal) {
|
|
21
|
+
const reason = signal.reason;
|
|
22
|
+
return reason instanceof Error ? reason : new DOMException("Aborted", "AbortError");
|
|
39
23
|
}
|
|
40
|
-
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
const OPENAI_WORKER_ID_STRIDE = 100;
|
|
44
|
-
function makeOpenAIWorkerId(tokenId, workerIndex) {
|
|
45
|
-
return tokenId * OPENAI_WORKER_ID_STRIDE + workerIndex;
|
|
24
|
+
function activeSignal(signal, timeoutMs) {
|
|
25
|
+
const timeout = AbortSignal.timeout(timeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS);
|
|
26
|
+
return signal ? AbortSignal.any([signal, timeout]) : timeout;
|
|
46
27
|
}
|
|
47
|
-
function
|
|
48
|
-
|
|
28
|
+
function quotaMessage(entries) {
|
|
29
|
+
const detail = entries.map((e) => `${e.name} (threshold ${e.threshold}%)`).join(", ");
|
|
30
|
+
return detail ? `All openai tokens exceeded quota threshold: ${detail}` : "All openai tokens exceeded quota threshold";
|
|
49
31
|
}
|
|
50
|
-
function
|
|
51
|
-
const
|
|
52
|
-
|
|
32
|
+
function inputItems(req) {
|
|
33
|
+
const history = req.coldHistory ?? [];
|
|
34
|
+
const content = req.coldInput.map((input) => {
|
|
35
|
+
if (input.type === "text") return {
|
|
36
|
+
type: "input_text",
|
|
37
|
+
text: input.text
|
|
38
|
+
};
|
|
39
|
+
if (input.type === "image") return {
|
|
40
|
+
type: "input_image",
|
|
41
|
+
image_url: input.url
|
|
42
|
+
};
|
|
43
|
+
if (input.type === "localImage") return {
|
|
44
|
+
type: "input_image",
|
|
45
|
+
image_url: input.path
|
|
46
|
+
};
|
|
47
|
+
return {
|
|
48
|
+
type: "input_text",
|
|
49
|
+
text: `${input.name}: ${input.path}`
|
|
50
|
+
};
|
|
51
|
+
});
|
|
52
|
+
return [...history, {
|
|
53
|
+
type: "message",
|
|
54
|
+
role: "user",
|
|
55
|
+
content
|
|
56
|
+
}];
|
|
57
|
+
}
|
|
58
|
+
function asReasoning(req) {
|
|
59
|
+
const summary = req.reasoningSummary && req.reasoningSummary !== "none" ? req.reasoningSummary : void 0;
|
|
60
|
+
if (!req.effort && !summary) return void 0;
|
|
61
|
+
return {
|
|
62
|
+
...req.effort ? { effort: req.effort } : {},
|
|
63
|
+
...summary ? { summary } : {}
|
|
64
|
+
};
|
|
53
65
|
}
|
|
66
|
+
function requestOptions(req) {
|
|
67
|
+
return {
|
|
68
|
+
model: req.model ?? "",
|
|
69
|
+
...req.systemPrompt ? { instructions: req.systemPrompt } : {},
|
|
70
|
+
history: inputItems(req),
|
|
71
|
+
...asReasoning(req) ? { reasoning: asReasoning(req) } : {},
|
|
72
|
+
...req.verbosity ? { verbosity: req.verbosity } : {},
|
|
73
|
+
...req.serviceTier ? { serviceTier: req.serviceTier === "fast" ? "priority" : req.serviceTier } : {},
|
|
74
|
+
...req.promptCacheKey ? { promptCacheKey: req.promptCacheKey } : {},
|
|
75
|
+
...req.outputSchema ? { outputSchema: { schema: req.outputSchema } } : {},
|
|
76
|
+
...req.imageGeneration ? { imageGeneration: req.imageGenerationOptions ? { ...req.imageGenerationOptions } : true } : {}
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Direct OpenAI dispatcher — Anthropic 과 동일한 stateless 실행 모델.
|
|
81
|
+
*
|
|
82
|
+
* 요청 = 토큰 선택(quota gate + weighted round-robin + cache affinity 선호) → HTTPS/WS
|
|
83
|
+
* 전송. permit/큐 같은 동시성 상한은 두지 않는다: 전송은 fetch 한 번이라 로컬 자원이
|
|
84
|
+
* 희소하지 않고, 상류 제한은 백엔드의 응답(429 등)이 진실이다. worker pool 시절의
|
|
85
|
+
* 큐 의미론(SERVER_BUSY, 큐 타임아웃)은 이 전환으로 제거됐다.
|
|
86
|
+
*/
|
|
54
87
|
var OpenAIDispatcher = class OpenAIDispatcher {
|
|
55
|
-
workerPool = /* @__PURE__ */ new Map();
|
|
56
88
|
tokenMetadata = /* @__PURE__ */ new Map();
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
this.poolConfig = poolConfig;
|
|
73
|
-
this.getHostAvailableGiB = getHostAvailableGiB;
|
|
89
|
+
transportKind;
|
|
90
|
+
rateLimitsCache = /* @__PURE__ */ new Map();
|
|
91
|
+
pendingRateLimits = /* @__PURE__ */ new Map();
|
|
92
|
+
clients = /* @__PURE__ */ new Map();
|
|
93
|
+
retiredClients = /* @__PURE__ */ new Set();
|
|
94
|
+
static RATE_LIMITS_CACHE_TTL = 6e4;
|
|
95
|
+
selector = new SmoothWeightedRoundRobin();
|
|
96
|
+
clientFactory;
|
|
97
|
+
fetchImpl;
|
|
98
|
+
quotaBlocked = /* @__PURE__ */ new Set();
|
|
99
|
+
inFlightCount = 0;
|
|
100
|
+
constructor(transportKind = resolveOpenAITransportKind(), dependencies = {}) {
|
|
101
|
+
this.transportKind = transportKind;
|
|
102
|
+
this.clientFactory = dependencies.clientFactory ?? ((options) => new OpenAIDirectClient(options));
|
|
103
|
+
this.fetchImpl = dependencies.fetch ?? fetch;
|
|
74
104
|
}
|
|
75
105
|
async start() {
|
|
76
|
-
this.stopped = false;
|
|
77
106
|
const { rows } = await TokenModel.findMany("A");
|
|
78
|
-
const
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
}));
|
|
84
|
-
this.scalerTimer = setInterval(() => this.requestAutoscaleEvaluation(), this.poolConfig.scaleIntervalMs);
|
|
85
|
-
this.scalerTimer.unref?.();
|
|
107
|
+
for (const row of rows) {
|
|
108
|
+
if (row.provider !== "openai") continue;
|
|
109
|
+
this.setToken(row.id, row.name, row.credentials, row.quota_threshold, row.weight, row.active);
|
|
110
|
+
}
|
|
111
|
+
logger.info(`started direct OpenAI runtime with ${this.tokenMetadata.size} tokens`);
|
|
86
112
|
}
|
|
87
113
|
async stop() {
|
|
88
|
-
this.
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
}
|
|
93
|
-
await this.scalingPromise?.catch(() => {});
|
|
94
|
-
this.rejectAllQueued("DISPATCHER_SHUTDOWN");
|
|
95
|
-
const kills = [...this.workerPool.values()].flat().map((w) => w.kill());
|
|
96
|
-
await Promise.allSettled(kills);
|
|
97
|
-
for (const id of this.tokenMetadata.keys()) this.weightedSelector.removeToken(id);
|
|
98
|
-
this.workerPool.clear();
|
|
114
|
+
for (const { client } of this.clients.values()) client.close?.();
|
|
115
|
+
this.clients.clear();
|
|
116
|
+
for (const entry of this.retiredClients) entry.client.close?.();
|
|
117
|
+
this.retiredClients.clear();
|
|
99
118
|
this.tokenMetadata.clear();
|
|
100
|
-
this.workerCursorByToken.clear();
|
|
101
|
-
this.weightedSelector.resetScores();
|
|
102
119
|
this.rateLimitsCache.clear();
|
|
103
|
-
this.
|
|
104
|
-
this.
|
|
105
|
-
this.startingTokenIds.clear();
|
|
120
|
+
this.quotaBlocked.clear();
|
|
121
|
+
this.selector.resetScores();
|
|
106
122
|
}
|
|
107
123
|
async onTokenAdded(id, name, credentials, quotaThreshold, weight = 1) {
|
|
108
|
-
this.
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
124
|
+
this.setToken(id, name, credentials, quotaThreshold, weight, true);
|
|
125
|
+
}
|
|
126
|
+
async onTokenUpdated(id, name, credentials, quotaThreshold, weight = 1) {
|
|
127
|
+
const old = this.tokenMetadata.get(id);
|
|
128
|
+
this.setToken(id, name, credentials, quotaThreshold, weight, old?.active ?? true);
|
|
113
129
|
}
|
|
114
130
|
async onTokenRemoved(id) {
|
|
115
|
-
|
|
116
|
-
const tokenName = workers[0]?.tokenName;
|
|
117
|
-
this.workerPool.delete(id);
|
|
131
|
+
this.retireClient(id);
|
|
118
132
|
this.tokenMetadata.delete(id);
|
|
119
|
-
this.
|
|
120
|
-
this.workerCursorByToken.delete(id);
|
|
133
|
+
this.selector.removeToken(id);
|
|
121
134
|
this.invalidateRateLimitsCache(id);
|
|
122
|
-
this.
|
|
123
|
-
await Promise.allSettled(workers.map((w) => w.kill()));
|
|
124
|
-
if (!this.hasActiveTokenCandidate(/* @__PURE__ */ new Set())) this.rejectAllQueued("NO_OPENAI_WORKERS");
|
|
125
|
-
if (workers.length > 0) {
|
|
126
|
-
const label = tokenName ?? `token ${id}`;
|
|
127
|
-
logger.info(`workers removed: ${label} (${workers.length})`);
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
async onTokenUpdated(id, name, credentials, quotaThreshold, weight = 1) {
|
|
131
|
-
const existing = this.workerPool.get(id) ?? [];
|
|
132
|
-
if (this.getQuotaThreshold(id) !== quotaThreshold) this.quotaBlockedTokenIds.delete(id);
|
|
133
|
-
this.setTokenMetadata(id, name, credentials, quotaThreshold, weight);
|
|
134
|
-
if (existing.length === 0) {
|
|
135
|
-
this.invalidateRateLimitsCache(id);
|
|
136
|
-
await this.spawnWorkers(id, name, credentials, quotaThreshold, weight);
|
|
137
|
-
return;
|
|
138
|
-
}
|
|
139
|
-
if (existing.every((w) => w.canReuseForToken(name, credentials))) {
|
|
140
|
-
existing.forEach((w) => w.updateTokenState(name, credentials));
|
|
141
|
-
logger.info(`workers updated in-place: ${name}`);
|
|
142
|
-
this.requestDrainQueue();
|
|
143
|
-
return;
|
|
144
|
-
}
|
|
145
|
-
this.workerPool.delete(id);
|
|
146
|
-
this.invalidateRateLimitsCache(id);
|
|
147
|
-
this.quotaBlockedTokenIds.delete(id);
|
|
148
|
-
await Promise.allSettled(existing.map((w) => w.kill()));
|
|
149
|
-
await this.spawnWorkers(id, name, credentials, quotaThreshold, weight);
|
|
135
|
+
this.quotaBlocked.delete(id);
|
|
150
136
|
}
|
|
151
137
|
onTokenDeactivated(id) {
|
|
152
|
-
const
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
if (metadata?.active) this.tokenMetadata.set(id, {
|
|
156
|
-
...metadata,
|
|
157
|
-
active: false
|
|
158
|
-
});
|
|
159
|
-
this.quotaBlockedTokenIds.delete(id);
|
|
160
|
-
const changed = workers.some((worker) => worker.active);
|
|
161
|
-
workers.forEach((w) => {
|
|
162
|
-
w.active = false;
|
|
163
|
-
});
|
|
164
|
-
if (changed) this.weightedSelector.resetScores();
|
|
165
|
-
if (!this.hasActiveTokenCandidate(/* @__PURE__ */ new Set())) this.rejectAllQueued("NO_ACTIVE_WORKERS");
|
|
166
|
-
const label = tokenName ?? `token ${id}`;
|
|
167
|
-
logger.info(`workers deactivated: ${label}`);
|
|
138
|
+
const token = this.tokenMetadata.get(id);
|
|
139
|
+
if (token) token.active = false;
|
|
140
|
+
this.selector.resetScores();
|
|
168
141
|
}
|
|
169
142
|
onTokenActivated(id) {
|
|
170
|
-
const
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
if (metadata && !metadata.active) this.tokenMetadata.set(id, {
|
|
174
|
-
...metadata,
|
|
175
|
-
active: true
|
|
176
|
-
});
|
|
177
|
-
const changed = workers.some((worker) => !worker.active);
|
|
178
|
-
workers.forEach((w) => {
|
|
179
|
-
w.active = true;
|
|
180
|
-
});
|
|
181
|
-
if (changed) this.weightedSelector.resetScores();
|
|
182
|
-
this.requestDrainQueue();
|
|
183
|
-
const label = tokenName ?? `token ${id}`;
|
|
184
|
-
logger.info(`workers activated: ${label}`);
|
|
143
|
+
const token = this.tokenMetadata.get(id);
|
|
144
|
+
if (token) token.active = true;
|
|
145
|
+
this.selector.resetScores();
|
|
185
146
|
}
|
|
186
147
|
async replaceTokens(rows) {
|
|
187
|
-
const
|
|
188
|
-
for (const id of
|
|
189
|
-
for (const row of rows)
|
|
190
|
-
if (this.workerPool.has(row.id)) await this.onTokenUpdated(row.id, row.name, row.credentials, row.quotaThreshold, row.weight);
|
|
191
|
-
else await this.onTokenAdded(row.id, row.name, row.credentials, row.quotaThreshold, row.weight);
|
|
192
|
-
this.onTokenActivated(row.id);
|
|
193
|
-
}
|
|
148
|
+
const ids = new Set(rows.map((r) => r.id));
|
|
149
|
+
for (const id of this.tokenMetadata.keys()) if (!ids.has(id)) await this.onTokenRemoved(id);
|
|
150
|
+
for (const row of rows) await this.onTokenUpdated(row.id, row.name, row.credentials, row.quotaThreshold, row.weight);
|
|
194
151
|
}
|
|
195
152
|
async generate(req) {
|
|
196
|
-
this.
|
|
197
|
-
const excludedTokenIds = /* @__PURE__ */ new Set();
|
|
198
|
-
const reuseWorker = await this.acquireReuseWorker(req, excludedTokenIds);
|
|
199
|
-
if (reuseWorker) {
|
|
200
|
-
logger.info(`↻ ${reuseWorker.tokenName}[${reuseWorker.tokenId}] (reuse thread, ${req.model})`);
|
|
201
|
-
return this.executeAndRelease(reuseWorker, (w) => this.executeTurn(w, req, req.reuse.threadId));
|
|
202
|
-
}
|
|
203
|
-
const worker = await this.acquireIdleWorker(excludedTokenIds);
|
|
204
|
-
if (worker) {
|
|
205
|
-
logger.info(`→ ${worker.tokenName}[${worker.tokenId}] (model: ${req.model})`);
|
|
206
|
-
return this.executeAndRelease(worker, (w) => this.executeTurn(w, req));
|
|
207
|
-
}
|
|
208
|
-
return this.enqueue((w) => {
|
|
209
|
-
logger.info(`→ ${w.tokenName}[${w.tokenId}] (model: ${req.model}, queued)`);
|
|
210
|
-
return this.executeTurn(w, req);
|
|
211
|
-
}, excludedTokenIds);
|
|
153
|
+
return this.run(req);
|
|
212
154
|
}
|
|
213
155
|
async generateStream(req, cb) {
|
|
214
|
-
this.lastRequestAt = Date.now();
|
|
215
156
|
if (req.imageGeneration) throw new ImageGenerationError("gate", "image generation is not supported on the streaming path");
|
|
216
|
-
const excludedTokenIds = /* @__PURE__ */ new Set();
|
|
217
|
-
const reuseWorker = await this.acquireReuseWorker(req, excludedTokenIds);
|
|
218
|
-
if (reuseWorker) {
|
|
219
|
-
logger.info(`↻ ${reuseWorker.tokenName}[${reuseWorker.tokenId}] (reuse thread, [stream])`);
|
|
220
|
-
return this.executeAndRelease(reuseWorker, (w) => this.executeStreamTurn(w, req, cb, req.reuse.threadId));
|
|
221
|
-
}
|
|
222
|
-
const worker = await this.acquireIdleWorker(excludedTokenIds);
|
|
223
|
-
if (worker) {
|
|
224
|
-
logger.info(`→ ${worker.tokenName}[${worker.tokenId}] (model: ${req.model}, [stream])`);
|
|
225
|
-
return this.executeAndRelease(worker, (w) => this.executeStreamTurn(w, req, cb));
|
|
226
|
-
}
|
|
227
|
-
return this.enqueue((w) => {
|
|
228
|
-
logger.info(`→ ${w.tokenName}[${w.tokenId}] (model: ${req.model}, [stream], queued)`);
|
|
229
|
-
return this.executeStreamTurn(w, req, cb);
|
|
230
|
-
}, excludedTokenIds);
|
|
231
|
-
}
|
|
232
|
-
async acquireReuseWorker(req, excludedTokenIds = /* @__PURE__ */ new Set()) {
|
|
233
|
-
if (req.imageGeneration) return null;
|
|
234
|
-
if (!THREAD_REUSE_ENABLED || !req.reuse) return null;
|
|
235
|
-
const { workerId, threadId, epoch } = req.reuse;
|
|
236
|
-
const worker = this.findWorkerById(workerId);
|
|
237
|
-
if (!worker || !worker.isReady || !worker.active) return null;
|
|
238
|
-
if (worker.epoch !== epoch) return null;
|
|
239
|
-
if (!worker.hasThread(threadId)) return null;
|
|
240
|
-
const quotaMetadata = this.tokenMetadata.get(worker.tokenId);
|
|
241
|
-
if (!await this.isTokenQuotaEligible(worker.tokenId, worker.tokenName, excludedTokenIds)) return null;
|
|
242
|
-
if (!worker.isReady || !worker.active || this.tokenMetadata.get(worker.tokenId) !== quotaMetadata || this.quotaBlockedTokenIds.has(worker.tokenId)) {
|
|
243
|
-
if (this.quotaBlockedTokenIds.has(worker.tokenId)) excludedTokenIds.add(worker.tokenId);
|
|
244
|
-
return null;
|
|
245
|
-
}
|
|
246
|
-
const deadline = Date.now() + REUSE_WORKER_WAIT_MS;
|
|
247
|
-
for (;;) {
|
|
248
|
-
if (!worker.isReady || !worker.active || worker.epoch !== epoch || !worker.hasThread(threadId) || this.tokenMetadata.get(worker.tokenId) !== quotaMetadata || this.quotaBlockedTokenIds.has(worker.tokenId)) {
|
|
249
|
-
if (this.quotaBlockedTokenIds.has(worker.tokenId)) excludedTokenIds.add(worker.tokenId);
|
|
250
|
-
return null;
|
|
251
|
-
}
|
|
252
|
-
if (worker.tryAcquireTurn()) return worker;
|
|
253
|
-
if (Date.now() >= deadline) return null;
|
|
254
|
-
await sleep(REUSE_WORKER_POLL_MS);
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
findWorkerById(workerId) {
|
|
258
|
-
for (const workers of this.workerPool.values()) for (const w of workers) if (makeOpenAIWorkerId(w.tokenId, w.workerIndex) === workerId) return w;
|
|
259
|
-
return null;
|
|
260
|
-
}
|
|
261
|
-
async interruptWorkerTurn(threadId, turnId) {
|
|
262
|
-
const allWorkers = [...this.workerPool.values()].flat().filter((w) => w.isReady);
|
|
263
|
-
await Promise.allSettled(allWorkers.map((w) => w.interruptTurn(threadId, turnId)));
|
|
264
|
-
}
|
|
265
|
-
async acquireIdleWorker(excludedTokenIds = /* @__PURE__ */ new Set()) {
|
|
266
|
-
const eligibility = await this.resolveTokenEligibility(excludedTokenIds);
|
|
267
|
-
if (eligibility.readyActiveTokenIds.size === 0) return null;
|
|
268
|
-
if (eligibility.eligibleTokenIds.size === 0) this.throwQuotaThresholdExceeded(eligibility);
|
|
269
|
-
const workersByToken = /* @__PURE__ */ new Map();
|
|
270
|
-
for (const worker of this.getAllReadyActiveWorkers()) {
|
|
271
|
-
if (!eligibility.eligibleTokenIds.has(worker.tokenId) || !worker.hasCapacity) continue;
|
|
272
|
-
const workers = workersByToken.get(worker.tokenId) ?? [];
|
|
273
|
-
workers.push(worker);
|
|
274
|
-
workersByToken.set(worker.tokenId, workers);
|
|
275
|
-
}
|
|
276
|
-
const selectedTokenId = this.weightedSelector.select(new Set(workersByToken.keys()));
|
|
277
|
-
if (selectedTokenId === null) return null;
|
|
278
|
-
const workers = workersByToken.get(selectedTokenId);
|
|
279
|
-
const cursor = this.workerCursorByToken.get(selectedTokenId) ?? 0;
|
|
280
|
-
for (let offset = 0; offset < workers.length; offset++) {
|
|
281
|
-
const index = (cursor + offset) % workers.length;
|
|
282
|
-
const worker = workers[index];
|
|
283
|
-
if (worker.tryAcquireTurn()) {
|
|
284
|
-
this.workerCursorByToken.set(selectedTokenId, (index + 1) % workers.length);
|
|
285
|
-
return worker;
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
throw new Error(`weighted token ${selectedTokenId} lost idle capacity during synchronous acquire`);
|
|
289
|
-
}
|
|
290
|
-
getAllReadyActiveWorkers() {
|
|
291
|
-
return [...this.workerPool.values()].flat().filter((w) => w.isReady && w.active);
|
|
292
|
-
}
|
|
293
|
-
async enqueue(execute, excludedTokenIds = /* @__PURE__ */ new Set()) {
|
|
294
|
-
const eligibility = await this.resolveTokenEligibility(excludedTokenIds);
|
|
295
|
-
if (eligibility.readyActiveTokenIds.size === 0 && !this.hasActiveTokenCandidate(excludedTokenIds)) throw new Error("NO_OPENAI_WORKERS");
|
|
296
|
-
if (eligibility.readyActiveTokenIds.size > 0 && eligibility.eligibleTokenIds.size === 0) this.throwQuotaThresholdExceeded(eligibility);
|
|
297
|
-
if (this.queue.length >= MAX_QUEUE_SIZE) throw new Error("SERVER_BUSY");
|
|
298
|
-
return new Promise((resolve, reject) => {
|
|
299
|
-
const item = {
|
|
300
|
-
resolve: (worker) => {
|
|
301
|
-
clearTimeout(item.timer);
|
|
302
|
-
item.abortCleanup?.();
|
|
303
|
-
Promise.resolve().then(() => this.executeAndRelease(worker, execute)).then(resolve, reject);
|
|
304
|
-
},
|
|
305
|
-
reject: (err) => {
|
|
306
|
-
clearTimeout(item.timer);
|
|
307
|
-
item.abortCleanup?.();
|
|
308
|
-
reject(err);
|
|
309
|
-
},
|
|
310
|
-
timer: setTimeout(() => {
|
|
311
|
-
this.removeFromQueue(item);
|
|
312
|
-
reject(/* @__PURE__ */ new Error("SERVER_BUSY"));
|
|
313
|
-
}, QUEUE_TIMEOUT_MS),
|
|
314
|
-
excludedTokenIds: new Set(excludedTokenIds)
|
|
315
|
-
};
|
|
316
|
-
this.queue.push(item);
|
|
317
|
-
this.requestDrainQueue();
|
|
318
|
-
this.requestAutoscaleEvaluation();
|
|
319
|
-
});
|
|
320
|
-
}
|
|
321
|
-
removeFromQueue(item) {
|
|
322
|
-
clearTimeout(item.timer);
|
|
323
|
-
item.abortCleanup?.();
|
|
324
|
-
const idx = this.queue.indexOf(item);
|
|
325
|
-
if (idx !== -1) this.queue.splice(idx, 1);
|
|
326
|
-
}
|
|
327
|
-
rejectAllQueued(reason) {
|
|
328
|
-
const err = new Error(reason);
|
|
329
|
-
this.queue.forEach((item) => {
|
|
330
|
-
clearTimeout(item.timer);
|
|
331
|
-
item.abortCleanup?.();
|
|
332
|
-
item.reject(err);
|
|
333
|
-
});
|
|
334
|
-
this.queue = [];
|
|
335
|
-
}
|
|
336
|
-
async drainQueue() {
|
|
337
|
-
if (this.draining) {
|
|
338
|
-
this.drainAgain = true;
|
|
339
|
-
return;
|
|
340
|
-
}
|
|
341
|
-
this.draining = true;
|
|
342
157
|
try {
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
} catch (e) {
|
|
348
|
-
logger.warn(`drainQueue failed: ${e.message}`);
|
|
349
|
-
} finally {
|
|
350
|
-
this.draining = false;
|
|
351
|
-
}
|
|
352
|
-
}
|
|
353
|
-
async drainQueueOnce() {
|
|
354
|
-
while (this.queue.length > 0) {
|
|
355
|
-
const next = this.queue[0];
|
|
356
|
-
let worker;
|
|
357
|
-
try {
|
|
358
|
-
worker = await this.acquireIdleWorker(next.excludedTokenIds);
|
|
359
|
-
} catch (e) {
|
|
360
|
-
if (e instanceof QuotaThresholdExceededError) {
|
|
361
|
-
this.queue.shift();
|
|
362
|
-
next.reject(e);
|
|
363
|
-
continue;
|
|
364
|
-
}
|
|
365
|
-
throw e;
|
|
366
|
-
}
|
|
367
|
-
if (!worker) break;
|
|
368
|
-
this.queue.shift();
|
|
369
|
-
next.resolve(worker);
|
|
158
|
+
cb.onComplete(await this.run(req, cb.onDelta));
|
|
159
|
+
} catch (error) {
|
|
160
|
+
cb.onError(error);
|
|
161
|
+
throw error;
|
|
370
162
|
}
|
|
371
163
|
}
|
|
372
|
-
async
|
|
164
|
+
async run(req, onDelta) {
|
|
165
|
+
const signal = activeSignal(req.abortSignal, req.timeoutMs);
|
|
166
|
+
if (signal.aborted) throw abortError(signal);
|
|
167
|
+
const selection = await this.selectToken(req.preferredTokenId, signal);
|
|
168
|
+
this.inFlightCount++;
|
|
373
169
|
try {
|
|
374
|
-
|
|
170
|
+
if (signal.aborted) throw abortError(signal);
|
|
171
|
+
return await this.runDirect(selection, {
|
|
172
|
+
...req,
|
|
173
|
+
abortSignal: signal
|
|
174
|
+
}, onDelta);
|
|
375
175
|
} finally {
|
|
376
|
-
|
|
377
|
-
this.requestDrainQueue();
|
|
176
|
+
this.inFlightCount--;
|
|
378
177
|
}
|
|
379
178
|
}
|
|
380
|
-
|
|
381
|
-
const
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
reasoningSummary: req.reasoningSummary,
|
|
391
|
-
serviceTier: req.serviceTier,
|
|
392
|
-
imageGeneration: req.imageGeneration,
|
|
393
|
-
imageGenerationOptions: req.imageGenerationOptions
|
|
179
|
+
async runDirect(selection, req, onDelta) {
|
|
180
|
+
const startedAt = Date.now();
|
|
181
|
+
let firstDeltaAt;
|
|
182
|
+
let text = "";
|
|
183
|
+
let usage = {
|
|
184
|
+
totalTokens: 0,
|
|
185
|
+
inputTokens: 0,
|
|
186
|
+
outputTokens: 0,
|
|
187
|
+
cachedInputTokens: 0,
|
|
188
|
+
reasoningOutputTokens: 0
|
|
394
189
|
};
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
190
|
+
const images = [];
|
|
191
|
+
let imageAttempted = false;
|
|
192
|
+
let servingModel = req.model ?? "";
|
|
193
|
+
const metadata = selection.metadata;
|
|
194
|
+
const clientEntry = this.acquireClient(selection);
|
|
195
|
+
try {
|
|
196
|
+
for await (const event of clientEntry.client.responses(requestOptions(req), req.abortSignal)) if (event.type === "text-delta") {
|
|
197
|
+
firstDeltaAt ??= Date.now();
|
|
198
|
+
text += event.text;
|
|
199
|
+
onDelta?.(event.text);
|
|
200
|
+
} else if (event.type === "image") {
|
|
201
|
+
imageAttempted = true;
|
|
202
|
+
images.push({
|
|
203
|
+
data: event.base64,
|
|
204
|
+
revisedPrompt: event.revisedPrompt ?? null
|
|
205
|
+
});
|
|
206
|
+
} else if (event.type === "output-item" && event.item.type === "image_generation_call") imageAttempted = true;
|
|
207
|
+
else if (event.type === "completed" && event.usage) {
|
|
208
|
+
servingModel = event.model ?? servingModel;
|
|
209
|
+
usage = {
|
|
210
|
+
totalTokens: event.usage.totalTokens,
|
|
211
|
+
inputTokens: event.usage.inputTokens,
|
|
212
|
+
outputTokens: event.usage.outputTokens,
|
|
213
|
+
cachedInputTokens: event.usage.cachedInputTokens,
|
|
214
|
+
reasoningOutputTokens: event.usage.reasoningTokens
|
|
215
|
+
};
|
|
216
|
+
} else if (event.type === "completed") servingModel = event.model ?? servingModel;
|
|
217
|
+
else if (event.type === "error") {
|
|
218
|
+
if (req.imageGeneration) throw new ImageGenerationError("incomplete", event.error.message);
|
|
219
|
+
throw event.error;
|
|
220
|
+
}
|
|
221
|
+
} finally {
|
|
222
|
+
this.releaseClient(clientEntry);
|
|
400
223
|
}
|
|
401
|
-
|
|
402
|
-
const result = await worker.executeTurn(turnReq, reuseThreadId);
|
|
403
|
-
if (req.imageGeneration && (!result.images || result.images.length === 0)) throw result.imageAttempted ? new ImageGenerationError("incomplete", "image tool ran but produced no completed image") : new ImageGenerationError("not_called", "model did not call the image_generation tool");
|
|
224
|
+
if (req.imageGeneration && images.length === 0) throw new ImageGenerationError(imageAttempted ? "incomplete" : "not_called", imageAttempted ? "image generation did not complete" : "model did not call image generation");
|
|
404
225
|
return {
|
|
405
|
-
text
|
|
406
|
-
tokenName:
|
|
407
|
-
usage
|
|
408
|
-
durationMs:
|
|
409
|
-
ttftMs:
|
|
410
|
-
model:
|
|
226
|
+
text,
|
|
227
|
+
tokenName: metadata.name,
|
|
228
|
+
usage,
|
|
229
|
+
durationMs: Date.now() - startedAt,
|
|
230
|
+
ttftMs: firstDeltaAt === void 0 ? null : firstDeltaAt - startedAt,
|
|
231
|
+
model: servingModel,
|
|
411
232
|
threadCoord: {
|
|
412
|
-
workerId:
|
|
413
|
-
threadId:
|
|
414
|
-
epoch:
|
|
233
|
+
workerId: selection.tokenId,
|
|
234
|
+
threadId: req.promptCacheKey ?? "",
|
|
235
|
+
epoch: -1
|
|
415
236
|
},
|
|
416
|
-
images:
|
|
237
|
+
...images.length ? { images } : {}
|
|
417
238
|
};
|
|
418
239
|
}
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
cb.onThreadId?.(threadId);
|
|
427
|
-
},
|
|
428
|
-
onComplete: (result) => {
|
|
429
|
-
cb.onComplete({
|
|
430
|
-
...result,
|
|
431
|
-
tokenName: worker.tokenName,
|
|
432
|
-
threadCoord: {
|
|
433
|
-
workerId: makeOpenAIWorkerId(worker.tokenId, worker.workerIndex),
|
|
434
|
-
threadId: resolvedThreadId,
|
|
435
|
-
epoch: worker.epoch
|
|
436
|
-
}
|
|
437
|
-
});
|
|
438
|
-
}
|
|
439
|
-
};
|
|
440
|
-
await worker.executeTurnStream(turnReq, wrappedCb, reuseThreadId);
|
|
441
|
-
}
|
|
442
|
-
async spawnWorkers(tokenId, tokenName, credentials, quotaThreshold, weight = 1) {
|
|
443
|
-
if (this.startingTokenIds.has(tokenId)) return;
|
|
444
|
-
this.startingTokenIds.add(tokenId);
|
|
445
|
-
this.setTokenMetadata(tokenId, tokenName, credentials, quotaThreshold, weight);
|
|
446
|
-
const expectedMetadata = this.tokenMetadata.get(tokenId);
|
|
447
|
-
const workers = [];
|
|
448
|
-
try {
|
|
449
|
-
for (let i = 0; i < this.poolConfig.minWorkersPerToken; i++) {
|
|
450
|
-
if (i > 0) await sleep(SPAWN_INTERVAL_MS);
|
|
451
|
-
const worker = await this.spawnSingleWorker(tokenId, tokenName, credentials, i);
|
|
452
|
-
if (worker) workers.push(worker);
|
|
453
|
-
}
|
|
454
|
-
if (!this.stopped && expectedMetadata?.active && this.tokenMetadata.get(tokenId) === expectedMetadata && !this.workerPool.has(tokenId)) {
|
|
455
|
-
if (workers.length > 0) this.workerPool.set(tokenId, workers);
|
|
456
|
-
} else await Promise.allSettled(workers.map((worker) => worker.kill()));
|
|
457
|
-
} finally {
|
|
458
|
-
this.startingTokenIds.delete(tokenId);
|
|
240
|
+
/** 세대가 바뀐 client 는 사용 중인 요청이 끝난 뒤에 닫는다. */
|
|
241
|
+
acquireClient(selection) {
|
|
242
|
+
const metadata = selection.metadata;
|
|
243
|
+
let entry = this.clients.get(selection.tokenId);
|
|
244
|
+
if (entry && entry.generation !== metadata.generation) {
|
|
245
|
+
this.retireClient(selection.tokenId);
|
|
246
|
+
entry = void 0;
|
|
459
247
|
}
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
248
|
+
if (!entry) {
|
|
249
|
+
const client = this.clientFactory({
|
|
250
|
+
credentials: {
|
|
251
|
+
accessToken: metadata.credentials.accessToken,
|
|
252
|
+
accountId: metadata.credentials.accountId
|
|
253
|
+
},
|
|
254
|
+
transportKind: this.transportKind,
|
|
255
|
+
fetch: this.fetchImpl,
|
|
256
|
+
refreshCredentials: async () => {
|
|
257
|
+
const refreshed = await handleChatgptAuthTokensRefresh(selection.tokenId);
|
|
258
|
+
const current = this.tokenMetadata.get(selection.tokenId);
|
|
259
|
+
if (current) current.credentials = {
|
|
260
|
+
...current.credentials,
|
|
261
|
+
accessToken: refreshed.accessToken,
|
|
262
|
+
accountId: refreshed.chatgptAccountId
|
|
263
|
+
};
|
|
264
|
+
return {
|
|
265
|
+
accessToken: refreshed.accessToken,
|
|
266
|
+
accountId: refreshed.chatgptAccountId
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
}, selection.tokenId);
|
|
270
|
+
entry = {
|
|
271
|
+
generation: metadata.generation,
|
|
272
|
+
client,
|
|
273
|
+
inFlight: 0,
|
|
274
|
+
retired: false
|
|
275
|
+
};
|
|
276
|
+
this.clients.set(selection.tokenId, entry);
|
|
486
277
|
}
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
if (
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
return;
|
|
278
|
+
entry.inFlight++;
|
|
279
|
+
return entry;
|
|
280
|
+
}
|
|
281
|
+
releaseClient(entry) {
|
|
282
|
+
entry.inFlight = Math.max(0, entry.inFlight - 1);
|
|
283
|
+
if (entry.retired && entry.inFlight === 0) {
|
|
284
|
+
this.retiredClients.delete(entry);
|
|
285
|
+
entry.client.close?.();
|
|
496
286
|
}
|
|
497
|
-
if (Date.now() - this.lastRequestAt >= this.poolConfig.scaleDownIdleMs) await this.scaleDownOneStep();
|
|
498
287
|
}
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
if (this.queue.length > 0) setTimeout(() => this.requestAutoscaleEvaluation(), Math.min(this.poolConfig.scaleIntervalMs, 1e3)).unref?.();
|
|
522
|
-
}
|
|
523
|
-
});
|
|
524
|
-
}
|
|
525
|
-
async ensureMinimumWorkersOneStep() {
|
|
526
|
-
const minimumDeficitTokenIds = /* @__PURE__ */ new Set();
|
|
527
|
-
if (this.stopped) return minimumDeficitTokenIds;
|
|
528
|
-
await this.runScaling(async () => {
|
|
529
|
-
const candidates = [...this.tokenMetadata.entries()].filter(([tokenId, metadata]) => {
|
|
530
|
-
if (!metadata.active || this.startingTokenIds.has(tokenId)) return false;
|
|
531
|
-
return (this.workerPool.get(tokenId)?.length ?? 0) < this.poolConfig.minWorkersPerToken;
|
|
532
|
-
});
|
|
533
|
-
if (candidates.length === 0) return;
|
|
534
|
-
candidates.forEach(([tokenId]) => minimumDeficitTokenIds.add(tokenId));
|
|
535
|
-
const added = (await Promise.all(candidates.map(([tokenId, metadata]) => this.spawnAndCommitWorker(tokenId, metadata, false)))).filter((worker) => worker !== null).length;
|
|
536
|
-
if (added > 0) {
|
|
537
|
-
logger.info(`openai worker pool repaired: +${added} workers (${this.workerCount} total)`);
|
|
538
|
-
this.requestDrainQueue();
|
|
539
|
-
if (this.queue.length > 0) setTimeout(() => this.requestAutoscaleEvaluation(), Math.min(this.poolConfig.scaleIntervalMs, 1e3)).unref?.();
|
|
540
|
-
}
|
|
541
|
-
});
|
|
542
|
-
return minimumDeficitTokenIds;
|
|
543
|
-
}
|
|
544
|
-
async scaleDownOneStep() {
|
|
545
|
-
if (!this.poolConfig.autoscale || this.stopped) return;
|
|
546
|
-
await this.runScaling(async () => {
|
|
547
|
-
const removed = [];
|
|
548
|
-
for (const tokenId of this.tokenMetadata.keys()) {
|
|
549
|
-
const workers = this.workerPool.get(tokenId) ?? [];
|
|
550
|
-
if (workers.length <= this.poolConfig.minWorkersPerToken) continue;
|
|
551
|
-
const worker = workers.toSorted((a, b) => b.workerIndex - a.workerIndex).find((entry) => entry.hasCapacity);
|
|
552
|
-
if (!worker) continue;
|
|
553
|
-
this.workerPool.set(tokenId, workers.filter((entry) => entry !== worker));
|
|
554
|
-
removed.push(worker);
|
|
555
|
-
}
|
|
556
|
-
if (removed.length === 0) return;
|
|
557
|
-
await Promise.allSettled(removed.map((worker) => worker.kill()));
|
|
558
|
-
logger.info(`openai autoscale down: -${removed.length} workers (${this.workerCount} total)`);
|
|
559
|
-
});
|
|
560
|
-
}
|
|
561
|
-
nextAvailableWorkerIndex(workers) {
|
|
562
|
-
const used = new Set(workers.map((worker) => worker.workerIndex));
|
|
563
|
-
for (let index = 0; index < this.poolConfig.maxWorkersPerToken; index++) if (!used.has(index)) return index;
|
|
564
|
-
return this.poolConfig.maxWorkersPerToken;
|
|
565
|
-
}
|
|
566
|
-
sweepIdleWorkerThreads() {
|
|
567
|
-
for (const worker of [...this.workerPool.values()].flat()) if (worker.isReady && worker.hasCapacity) worker.sweepIdleThreads();
|
|
568
|
-
}
|
|
569
|
-
async spawnAndCommitWorker(tokenId, metadata, respectQuotaBlock) {
|
|
570
|
-
const expectedWorkers = this.workerPool.get(tokenId);
|
|
571
|
-
const workerIndex = this.nextAvailableWorkerIndex(expectedWorkers ?? []);
|
|
572
|
-
if (workerIndex >= this.poolConfig.maxWorkersPerToken) return null;
|
|
573
|
-
const worker = await this.spawnSingleWorker(tokenId, metadata.name, metadata.credentials, workerIndex);
|
|
574
|
-
if (!worker) return null;
|
|
575
|
-
const currentMetadata = this.tokenMetadata.get(tokenId);
|
|
576
|
-
const currentWorkers = this.workerPool.get(tokenId);
|
|
577
|
-
if (!currentMetadata?.active || currentMetadata !== metadata || currentWorkers !== expectedWorkers || respectQuotaBlock && this.quotaBlockedTokenIds.has(tokenId) || currentWorkers?.some((entry) => entry.workerIndex === workerIndex)) {
|
|
578
|
-
await worker.kill().catch(() => {});
|
|
579
|
-
return null;
|
|
288
|
+
/** map 에서 떼어내고, 진행 중인 요청이 없을 때만 즉시 닫는다. */
|
|
289
|
+
retireClient(tokenId) {
|
|
290
|
+
const entry = this.clients.get(tokenId);
|
|
291
|
+
if (!entry) return;
|
|
292
|
+
this.clients.delete(tokenId);
|
|
293
|
+
entry.retired = true;
|
|
294
|
+
if (entry.inFlight === 0) entry.client.close?.();
|
|
295
|
+
else this.retiredClients.add(entry);
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* 토큰 선택 — quota gate 를 통과한 active 토큰 중에서 고른다. cache affinity 선호
|
|
299
|
+
* 토큰이 eligible 하면 그 판정만으로 즉시 결정하고(전체 sweep 생략, weighted 상태
|
|
300
|
+
* 비변경), 아니면 병렬 quota 판정 후 smooth weighted round-robin. 동시성 상한이
|
|
301
|
+
* 없으므로 "빈 자리" 개념도 없다 — 선택 즉시 실행이다.
|
|
302
|
+
*/
|
|
303
|
+
async selectToken(preferredTokenId, signal) {
|
|
304
|
+
if (preferredTokenId !== void 0) {
|
|
305
|
+
const preferred = this.tokenMetadata.get(preferredTokenId);
|
|
306
|
+
if (preferred?.active && await this.isQuotaEligible(preferredTokenId, preferred, signal)) return {
|
|
307
|
+
tokenId: preferredTokenId,
|
|
308
|
+
metadata: preferred
|
|
309
|
+
};
|
|
580
310
|
}
|
|
581
|
-
const
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
this.evaluateAutoscaling().catch((e) => logger.warn(`openai autoscale evaluation failed: ${e.message}`));
|
|
601
|
-
}
|
|
602
|
-
async runScaling(task) {
|
|
603
|
-
if (this.scalingPromise) {
|
|
604
|
-
await this.scalingPromise;
|
|
605
|
-
return;
|
|
311
|
+
const checks = await Promise.all([...this.tokenMetadata.entries()].filter(([, token]) => token.active).map(async ([id, token]) => ({
|
|
312
|
+
id,
|
|
313
|
+
token,
|
|
314
|
+
eligible: await this.isQuotaEligible(id, token, signal)
|
|
315
|
+
})));
|
|
316
|
+
const eligible = new Set(checks.filter((c) => c.eligible).map((c) => c.id));
|
|
317
|
+
if (eligible.size === 0) {
|
|
318
|
+
const over = checks.filter((c) => !c.eligible && c.token.quotaThreshold !== null && c.token.quotaThreshold !== void 0).map((c) => ({
|
|
319
|
+
name: c.token.name,
|
|
320
|
+
threshold: c.token.quotaThreshold
|
|
321
|
+
}));
|
|
322
|
+
if (over.length) {
|
|
323
|
+
logger.warn("quota_threshold gate: all_exceeded", {
|
|
324
|
+
provider: "openai",
|
|
325
|
+
overThresholdTokens: over
|
|
326
|
+
});
|
|
327
|
+
throw new QuotaThresholdExceededError(quotaMessage(over));
|
|
328
|
+
}
|
|
329
|
+
throw new Error("NO_OPENAI_WORKERS");
|
|
606
330
|
}
|
|
607
|
-
const
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
this.scalingPromise = scaling;
|
|
611
|
-
await scaling;
|
|
612
|
-
}
|
|
613
|
-
rateLimitsCache = /* @__PURE__ */ new Map();
|
|
614
|
-
static RATE_LIMITS_CACHE_TTL = 6e4;
|
|
615
|
-
async getRateLimitsByTokenId(tokenId) {
|
|
616
|
-
const generation = this.rateLimitsGenerationByToken.get(tokenId) ?? 0;
|
|
617
|
-
const cached = this.rateLimitsCache.get(tokenId);
|
|
618
|
-
if (cached && cached.generation === generation && Date.now() - cached.cachedAt < OpenAIDispatcher.RATE_LIMITS_CACHE_TTL) return {
|
|
619
|
-
data: cached.data,
|
|
620
|
-
cachedAt: cached.cachedAt
|
|
621
|
-
};
|
|
622
|
-
const worker = (this.workerPool.get(tokenId) ?? []).find((w) => w.isReady);
|
|
623
|
-
if (!worker) throw new Error("no ready openai workers");
|
|
624
|
-
const entry = {
|
|
625
|
-
data: await worker.getRateLimits(),
|
|
626
|
-
cachedAt: Date.now(),
|
|
627
|
-
generation
|
|
628
|
-
};
|
|
629
|
-
if ((this.rateLimitsGenerationByToken.get(tokenId) ?? 0) === generation) this.rateLimitsCache.set(tokenId, entry);
|
|
331
|
+
const selected = this.selector.select(eligible);
|
|
332
|
+
const metadata = selected !== null ? this.tokenMetadata.get(selected) : void 0;
|
|
333
|
+
if (selected === null || !metadata) throw new Error("NO_OPENAI_WORKERS");
|
|
630
334
|
return {
|
|
631
|
-
|
|
632
|
-
|
|
335
|
+
tokenId: selected,
|
|
336
|
+
metadata
|
|
633
337
|
};
|
|
634
338
|
}
|
|
635
|
-
|
|
636
|
-
this.
|
|
637
|
-
|
|
638
|
-
invalidateRateLimitsCache(tokenId) {
|
|
639
|
-
this.rateLimitsCache.delete(tokenId);
|
|
640
|
-
this.rateLimitsGenerationByToken.set(tokenId, (this.rateLimitsGenerationByToken.get(tokenId) ?? 0) + 1);
|
|
641
|
-
}
|
|
642
|
-
setTokenMetadata(id, name, credentials, quotaThreshold, weight) {
|
|
643
|
-
this.tokenMetadata.set(id, {
|
|
339
|
+
setToken(id, name, credentials, quotaThreshold, weight, active) {
|
|
340
|
+
const old = this.tokenMetadata.get(id);
|
|
341
|
+
if (old) Object.assign(old, {
|
|
644
342
|
name,
|
|
645
343
|
credentials,
|
|
646
344
|
quotaThreshold,
|
|
647
345
|
weight,
|
|
648
|
-
active
|
|
346
|
+
active,
|
|
347
|
+
generation: old.generation + 1
|
|
649
348
|
});
|
|
650
|
-
this.
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
}
|
|
658
|
-
hasQuotaThreshold(tokenId) {
|
|
659
|
-
const threshold = this.getQuotaThreshold(tokenId);
|
|
660
|
-
return threshold !== void 0 && threshold !== null;
|
|
661
|
-
}
|
|
662
|
-
async resolveTokenEligibility(excludedTokenIds) {
|
|
663
|
-
const workers = this.getAllReadyActiveWorkers();
|
|
664
|
-
const byToken = /* @__PURE__ */ new Map();
|
|
665
|
-
for (const worker of workers) if (!byToken.has(worker.tokenId)) byToken.set(worker.tokenId, worker.tokenName);
|
|
666
|
-
const readyActiveTokenIds = new Set(byToken.keys());
|
|
667
|
-
const eligibleTokenIds = /* @__PURE__ */ new Set();
|
|
668
|
-
const overThresholdTokens = [];
|
|
669
|
-
let thresholdedTokenCount = 0;
|
|
670
|
-
const entries = Array.from(byToken.entries());
|
|
671
|
-
(await Promise.allSettled(entries.map(async ([tokenId, tokenName]) => {
|
|
672
|
-
if (excludedTokenIds.has(tokenId)) {
|
|
673
|
-
thresholdedTokenCount++;
|
|
674
|
-
return {
|
|
675
|
-
tokenId,
|
|
676
|
-
tokenName,
|
|
677
|
-
eligible: false
|
|
678
|
-
};
|
|
679
|
-
}
|
|
680
|
-
if (!this.hasQuotaThreshold(tokenId)) return {
|
|
681
|
-
tokenId,
|
|
682
|
-
tokenName,
|
|
683
|
-
eligible: true
|
|
684
|
-
};
|
|
685
|
-
thresholdedTokenCount++;
|
|
686
|
-
return {
|
|
687
|
-
tokenId,
|
|
688
|
-
tokenName,
|
|
689
|
-
eligible: await this.isTokenQuotaEligible(tokenId, tokenName)
|
|
690
|
-
};
|
|
691
|
-
}))).forEach((check, index) => {
|
|
692
|
-
if (check.status === "fulfilled") {
|
|
693
|
-
if (check.value.eligible) eligibleTokenIds.add(check.value.tokenId);
|
|
694
|
-
else {
|
|
695
|
-
const threshold = this.getQuotaThreshold(check.value.tokenId);
|
|
696
|
-
if (threshold !== void 0 && threshold !== null) overThresholdTokens.push({
|
|
697
|
-
tokenName: check.value.tokenName,
|
|
698
|
-
threshold
|
|
699
|
-
});
|
|
700
|
-
}
|
|
701
|
-
return;
|
|
702
|
-
}
|
|
703
|
-
const entry = entries[index];
|
|
704
|
-
if (entry) {
|
|
705
|
-
const [tokenId, tokenName] = entry;
|
|
706
|
-
this.logQuotaLookupFailOpen(tokenId, tokenName, String(check.reason));
|
|
707
|
-
eligibleTokenIds.add(tokenId);
|
|
708
|
-
}
|
|
349
|
+
else this.tokenMetadata.set(id, {
|
|
350
|
+
name,
|
|
351
|
+
credentials,
|
|
352
|
+
quotaThreshold,
|
|
353
|
+
weight,
|
|
354
|
+
active,
|
|
355
|
+
generation: 1
|
|
709
356
|
});
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
overThresholdTokens,
|
|
714
|
-
thresholdedTokenCount
|
|
715
|
-
};
|
|
357
|
+
this.selector.setToken(id, weight);
|
|
358
|
+
this.invalidateRateLimitsCache(id);
|
|
359
|
+
this.quotaBlocked.delete(id);
|
|
716
360
|
}
|
|
717
|
-
async
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
361
|
+
async getRateLimitsByTokenId(tokenId, signal) {
|
|
362
|
+
const token = this.tokenMetadata.get(tokenId);
|
|
363
|
+
if (!token) throw new Error(`openai token ${tokenId} not found`);
|
|
364
|
+
const cached = this.rateLimitsCache.get(tokenId);
|
|
365
|
+
if (cached && cached.generation === token.generation && Date.now() - cached.cachedAt < OpenAIDispatcher.RATE_LIMITS_CACHE_TTL) return cached;
|
|
366
|
+
const pending = this.pendingRateLimits.get(tokenId);
|
|
367
|
+
if (pending) return pending;
|
|
368
|
+
const fetchPromise = (async () => {
|
|
369
|
+
const result = await readOpenAIQuotaUsage({
|
|
370
|
+
credentials: token.credentials,
|
|
371
|
+
fetch: this.fetchImpl,
|
|
372
|
+
...signal ? { signal } : {}
|
|
373
|
+
});
|
|
374
|
+
if (result.kind === "lookup_failed") throw new Error(result.reason);
|
|
375
|
+
if (!result.raw) throw new Error("OpenAI quota response missing raw rate limits");
|
|
376
|
+
const entry = {
|
|
377
|
+
data: result.raw,
|
|
378
|
+
cachedAt: Date.now(),
|
|
379
|
+
generation: token.generation
|
|
380
|
+
};
|
|
381
|
+
if (this.tokenMetadata.get(tokenId) === token) this.rateLimitsCache.set(tokenId, entry);
|
|
382
|
+
return entry;
|
|
383
|
+
})().finally(() => this.pendingRateLimits.delete(tokenId));
|
|
384
|
+
this.pendingRateLimits.set(tokenId, fetchPromise);
|
|
385
|
+
return fetchPromise;
|
|
386
|
+
}
|
|
387
|
+
async isQuotaEligible(id, token, signal) {
|
|
388
|
+
if (token.quotaThreshold === null || token.quotaThreshold === void 0) return true;
|
|
389
|
+
const generation = token.generation;
|
|
390
|
+
const result = await readOpenAIQuotaUsage(async () => this.getRateLimitsByTokenId(id, signal));
|
|
391
|
+
if (this.tokenMetadata.get(id) !== token || token.generation !== generation) return false;
|
|
392
|
+
if (result.kind === "lookup_failed") {
|
|
393
|
+
this.quotaBlocked.delete(id);
|
|
394
|
+
logger.warn("quota_threshold gate: lookup_fail_open", {
|
|
395
|
+
tokenId: id,
|
|
396
|
+
tokenName: token.name,
|
|
397
|
+
lookupReason: result.reason
|
|
398
|
+
});
|
|
748
399
|
return true;
|
|
749
400
|
}
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
tokenName,
|
|
755
|
-
provider: "openai",
|
|
756
|
-
threshold,
|
|
757
|
-
cachedUtilization: result.utilizationPct,
|
|
758
|
-
cacheAge: result.cacheAgeMs,
|
|
759
|
-
windowDurationMins: result.windowDurationMins,
|
|
760
|
-
resetsAt: result.resetsAt,
|
|
761
|
-
limitId: result.limitId,
|
|
762
|
-
reason: "over_threshold"
|
|
763
|
-
});
|
|
764
|
-
}
|
|
765
|
-
logQuotaRecovered(tokenId, tokenName, threshold, result) {
|
|
766
|
-
logger.info(`quota_threshold gate: recovered ${tokenName}[${tokenId}] (${result.utilizationPct}% < ${threshold}%)`, {
|
|
767
|
-
tokenId,
|
|
768
|
-
tokenName,
|
|
769
|
-
provider: "openai",
|
|
770
|
-
threshold,
|
|
771
|
-
cachedUtilization: result.utilizationPct,
|
|
772
|
-
cacheAge: result.cacheAgeMs,
|
|
773
|
-
windowDurationMins: result.windowDurationMins,
|
|
774
|
-
resetsAt: result.resetsAt,
|
|
775
|
-
limitId: result.limitId,
|
|
776
|
-
reason: "recovered"
|
|
777
|
-
});
|
|
778
|
-
}
|
|
779
|
-
logQuotaLookupFailOpen(tokenId, tokenName, reason) {
|
|
780
|
-
const threshold = this.getQuotaThreshold(tokenId);
|
|
781
|
-
logger.warn("quota_threshold gate: lookup_fail_open", {
|
|
782
|
-
tokenId,
|
|
783
|
-
tokenName,
|
|
784
|
-
provider: "openai",
|
|
785
|
-
threshold,
|
|
786
|
-
reason: "lookup_fail_open",
|
|
787
|
-
lookupReason: reason
|
|
788
|
-
});
|
|
789
|
-
}
|
|
790
|
-
throwQuotaThresholdExceeded(eligibility) {
|
|
791
|
-
logger.warn("quota_threshold gate: all_exceeded", {
|
|
792
|
-
provider: "openai",
|
|
793
|
-
tokenCount: eligibility.readyActiveTokenIds.size,
|
|
794
|
-
thresholdedTokenCount: eligibility.thresholdedTokenCount,
|
|
795
|
-
overThresholdTokens: eligibility.overThresholdTokens,
|
|
796
|
-
reason: "all_exceeded"
|
|
797
|
-
});
|
|
798
|
-
throw new QuotaThresholdExceededError(quotaThresholdExceededMessage("openai", eligibility.overThresholdTokens));
|
|
799
|
-
}
|
|
800
|
-
pendingLogin = null;
|
|
801
|
-
async startBrowserLogin(name) {
|
|
802
|
-
if (this.pendingLogin) {
|
|
803
|
-
this.pendingLogin.worker.kill().catch(() => {});
|
|
804
|
-
clearTimeout(this.pendingLogin.timer);
|
|
805
|
-
this.pendingLogin = null;
|
|
806
|
-
}
|
|
807
|
-
const worker = new CodexAppServerWorker({
|
|
808
|
-
tokenId: Date.now(),
|
|
809
|
-
tokenName: name,
|
|
810
|
-
accessToken: "",
|
|
811
|
-
accountId: ""
|
|
812
|
-
});
|
|
813
|
-
const authUrl = await worker.startBrowserLogin();
|
|
814
|
-
const timer = setTimeout(() => {
|
|
815
|
-
if (this.pendingLogin?.worker === worker) {
|
|
816
|
-
logger.warn(`browser login timeout for ${name}, killing worker`);
|
|
817
|
-
worker.kill().catch(() => {});
|
|
818
|
-
this.pendingLogin = null;
|
|
819
|
-
}
|
|
820
|
-
}, 3e5);
|
|
821
|
-
this.pendingLogin = {
|
|
822
|
-
worker,
|
|
823
|
-
name,
|
|
824
|
-
timer
|
|
825
|
-
};
|
|
826
|
-
return { authUrl };
|
|
827
|
-
}
|
|
828
|
-
get pendingLoginName() {
|
|
829
|
-
return this.pendingLogin?.name ?? null;
|
|
830
|
-
}
|
|
831
|
-
async completeBrowserLogin() {
|
|
832
|
-
if (!this.pendingLogin) throw new Error("no pending login");
|
|
833
|
-
const { worker, timer } = this.pendingLogin;
|
|
834
|
-
try {
|
|
835
|
-
await worker.waitForBrowserLoginComplete();
|
|
836
|
-
const creds = await worker.readManagedCredentials();
|
|
837
|
-
if (!creds) throw new Error("failed to read credentials after login");
|
|
838
|
-
return creds;
|
|
839
|
-
} finally {
|
|
840
|
-
clearTimeout(timer);
|
|
841
|
-
this.pendingLogin = null;
|
|
842
|
-
await worker.kill().catch(() => {});
|
|
401
|
+
if (result.utilizationPct >= token.quotaThreshold) {
|
|
402
|
+
if (!this.quotaBlocked.has(id)) logger.info(`quota_threshold gate: over_threshold ${token.name}[${id}] (${result.utilizationPct}% >= ${token.quotaThreshold}%)`);
|
|
403
|
+
this.quotaBlocked.add(id);
|
|
404
|
+
return false;
|
|
843
405
|
}
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
406
|
+
if (this.quotaBlocked.delete(id)) logger.info(`quota_threshold gate: recovered ${token.name}[${id}] (${result.utilizationPct}% < ${token.quotaThreshold}%)`);
|
|
407
|
+
return true;
|
|
408
|
+
}
|
|
409
|
+
invalidateRateLimitsCache(id) {
|
|
410
|
+
this.rateLimitsCache.delete(id);
|
|
411
|
+
}
|
|
412
|
+
get tokenCount() {
|
|
413
|
+
return [...this.tokenMetadata.values()].filter((t) => t.active).length;
|
|
414
|
+
}
|
|
415
|
+
get inFlight() {
|
|
416
|
+
return this.inFlightCount;
|
|
417
|
+
}
|
|
418
|
+
/**
|
|
419
|
+
* 토큰별 쿼터 스냅샷 — 신선한(rate limits TTL 내) 캐시만 읽고 절대 fetch 하지 않는다.
|
|
420
|
+
* monit vitals 는 로그 폴링에 편승하는 값이라 여기서 네트워크를 타면 안 된다.
|
|
421
|
+
* threshold 미설정 토큰은 쿼터 판정을 돌지 않아 usedPercent 가 null 로 남을 수 있다.
|
|
422
|
+
*/
|
|
423
|
+
get quotaByToken() {
|
|
424
|
+
const now = Date.now();
|
|
425
|
+
return [...this.tokenMetadata.entries()].map(([id, t]) => {
|
|
426
|
+
const cached = this.rateLimitsCache.get(id);
|
|
427
|
+
const primary = cached !== void 0 && cached.generation === t.generation && now - cached.cachedAt < OpenAIDispatcher.RATE_LIMITS_CACHE_TTL ? cached.data.rateLimits?.primary : void 0;
|
|
428
|
+
return {
|
|
429
|
+
name: t.name,
|
|
430
|
+
usedPercent: primary?.usedPercent ?? null,
|
|
431
|
+
threshold: t.quotaThreshold ?? null,
|
|
432
|
+
blocked: this.quotaBlocked.has(id),
|
|
433
|
+
resetsAt: primary?.resetsAt !== null && primary?.resetsAt !== void 0 ? primary.resetsAt * 1e3 : null
|
|
434
|
+
};
|
|
435
|
+
}).toSorted((a, b) => a.name.localeCompare(b.name));
|
|
859
436
|
}
|
|
860
437
|
};
|
|
861
438
|
//#endregion
|
|
862
|
-
export { ImageGenerationError, OpenAIDispatcher
|
|
439
|
+
export { ImageGenerationError, OpenAIDispatcher };
|
|
863
440
|
|
|
864
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3BlbmFpLWRpc3BhdGNoZXIuanMiLCJuYW1lcyI6W10sInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL3V0aWxzL3Byb3ZpZGVycy9vcGVuYWkvb3BlbmFpLWRpc3BhdGNoZXIudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBPcGVuQUlEaXNwYXRjaGVyIOKAlCBjb2RleCBhcHAtc2VydmVyIHdvcmtlciBwb29sICsg7Yag7YGwIOudvOyasO2MhS5cbiAqXG4gKiAtIO2GoO2BsOuLuSBDb2RleEFwcFNlcnZlcldvcmtlciDsnpDrj5kg7ZmV7J6lICjquLDrs7ggMX4zLCBoYXJkIGNhcCAyMClcbiAqIC0gaWRsZSB3b3JrZXIgcm91bmQtcm9iaW4g7ISg7YOdICsg7YGQIOuMgOq4sCAo7KCE67aAIGJ1c3kg7IucKVxuICogLSBUb2tlblN1YnNjcmliZXIg7J2067Kk7Yq466GcIHdvcmtlciBwb29sIOuPmeq4sO2ZlFxuICogLSBiYWNrcHJlc3N1cmU6IO2BkCBmdWxsIOuYkOuKlCB0aW1lb3V0IOyLnCBTRVJWRVJfQlVTWVxuICovXG5pbXBvcnQgeyByZWFkRmlsZVN5bmMgfSBmcm9tIFwibm9kZTpmc1wiO1xuaW1wb3J0IHsgZnJlZW1lbSB9IGZyb20gXCJub2RlOm9zXCI7XG5cbmltcG9ydCB7IGdldExvZ2dlciB9IGZyb20gXCJAbG9ndGFwZS9sb2d0YXBlXCI7XG5cbmltcG9ydCB7IFF1b3RhVGhyZXNob2xkRXhjZWVkZWRFcnJvciB9IGZyb20gXCIuLi8uLi8uLi9hcHBsaWNhdGlvbi9xZ3JpZC9xZ3JpZC50eXBlc1wiO1xuaW1wb3J0IHsgVG9rZW5Nb2RlbCB9IGZyb20gXCIuLi8uLi8uLi9hcHBsaWNhdGlvbi90b2tlbi90b2tlbi5tb2RlbFwiO1xuaW1wb3J0IHsgdHlwZSBPcGVuQUlDcmVkZW50aWFscyB9IGZyb20gXCIuLi8uLi8uLi9hcHBsaWNhdGlvbi90b2tlbi90b2tlbi50eXBlc1wiO1xuaW1wb3J0IHsgdHlwZSBHZXRBY2NvdW50UmF0ZUxpbWl0c1Jlc3BvbnNlIH0gZnJvbSBcIi4uLy4uLy4uL2NvZGV4LXByb3RvY29sL3YyL0dldEFjY291bnRSYXRlTGltaXRzUmVzcG9uc2VcIjtcbmltcG9ydCB7XG4gIHR5cGUgR2VuZXJhdGVSZXF1ZXN0LFxuICB0eXBlIEdlbmVyYXRlUmVzdWx0LFxuICB0eXBlIEdlbmVyYXRlU3RyZWFtQ2FsbGJhY2tzLFxuICB0eXBlIFByb3ZpZGVyRGlzcGF0Y2hlcixcbn0gZnJvbSBcIi4uL2NvbW1vbi9wcm92aWRlci1kaXNwYXRjaGVyXCI7XG5pbXBvcnQgeyBTbW9vdGhXZWlnaHRlZFJvdW5kUm9iaW4gfSBmcm9tIFwiLi4vY29tbW9uL3Ntb290aC13ZWlnaHRlZC1yb3VuZC1yb2JpblwiO1xuaW1wb3J0IHsgQ29kZXhBcHBTZXJ2ZXJXb3JrZXIsIHR5cGUgU3RyZWFtQ2FsbGJhY2tzLCB0eXBlIFR1cm5SZXF1ZXN0IH0gZnJvbSBcIi4vY29kZXgtd29ya2VyXCI7XG5pbXBvcnQge1xuICByZWFkT3BlbkFJUXVvdGFVc2FnZSxcbiAgdHlwZSBPcGVuQUlRdW90YVVzYWdlUmVzdWx0LFxuICB0eXBlIE9wZW5BSVJhdGVMaW1pdHNXaXRoTWV0YSxcbn0gZnJvbSBcIi4vb3BlbmFpLXF1b3RhXCI7XG5pbXBvcnQgeyBoYW5kbGVDaGF0Z3B0QXV0aFRva2Vuc1JlZnJlc2ggfSBmcm9tIFwiLi9vcGVuYWktcmVmcmVzaFwiO1xuaW1wb3J0IHtcbiAgZXN0aW1hdGVPcGVuQUlXb3JrZXJSc3NHaUIsXG4gIHR5cGUgT3BlbkFJV29ya2VyUG9vbENvbmZpZyxcbiAgcmVzb2x2ZU9wZW5BSVdvcmtlclBvb2xDb25maWcsXG59IGZyb20gXCIuL29wZW5haS13b3JrZXItcG9vbC1jb25maWdcIjtcblxuY29uc3QgbG9nZ2VyID0gZ2V0TG9nZ2VyKFtcInFncmlkXCIsIFwib3BlbmFpLWRpc3BhdGNoZXJcIl0pO1xuXG4vLyDsnbTrr7jsp4Ag7IOd7ISxIOyalOyyreydtCDqsozsnbTtirgv7IOd7ISx7JeQIOyLpO2MqO2WiOydhCDrlYzsnZgg6rWs67aE7J6QLlxuLy8gLSBcImdhdGVcIjog7IKs7KCEIOqygOymnSDsi6TtjKgoY2FwYWJpbGl0eS/rqqjrjbgg66mA7Yuw66qo64usIOu2iOy2qeyhsSkg4oCUIHR1cm4g66+47Iuk7ZaJLlxuLy8gLSBcIm5vdF9jYWxsZWRcIjogdHVybiDsnYAg7ISx6rO17ZaI7Jy864KYIOuqqOuNuOydtCBpbWFnZSB0b29sIOydhCDtmLjstpwg7JWIIO2VqCDigJQg7J6s7Iuc64+EIOustOydtSjtlITroaztlITtirgg66y47KCcKS5cbi8vIC0gXCJpbmNvbXBsZXRlXCI6IHRvb2wg7Iuc64+E65CQ7Jy864KYIOyZhOyEsSDsnbTrr7jsp4Ag66+464+E7LCpIOKAlCDsnqzsi5zrj4Qg7ZuE67O0KOyEnOuyhOy4oSDsi6TtjKgv6rGw67aAKS5cbmV4cG9ydCB0eXBlIEltYWdlRmFpbHVyZUtpbmQgPSBcImdhdGVcIiB8IFwibm90X2NhbGxlZFwiIHwgXCJpbmNvbXBsZXRlXCI7XG5cbmV4cG9ydCBjbGFzcyBJbWFnZUdlbmVyYXRpb25FcnJvciBleHRlbmRzIEVycm9yIHtcbiAgY29uc3RydWN0b3IoXG4gICAgcmVhZG9ubHkga2luZDogSW1hZ2VGYWlsdXJlS2luZCxcbiAgICBtZXNzYWdlOiBzdHJpbmcsXG4gICkge1xuICAgIHN1cGVyKG1lc3NhZ2UpO1xuICAgIHRoaXMubmFtZSA9IFwiSW1hZ2VHZW5lcmF0aW9uRXJyb3JcIjtcbiAgfVxufVxuXG5jb25zdCBERUZBVUxUX0VGRk9SVCA9IFwibG93XCI7XG5jb25zdCBRVUVVRV9USU1FT1VUX01TID0gNjBfMDAwO1xuY29uc3QgTUFYX1FVRVVFX1NJWkUgPSA1MDtcbmNvbnN0IFNQQVdOX0lOVEVSVkFMX01TID0gNTAwO1xuXG5mdW5jdGlvbiByZWFkSG9zdEF2YWlsYWJsZUdpQigpOiBudW1iZXIge1xuICB0cnkge1xuICAgIGNvbnN0IG1hdGNoID0gcmVhZEZpbGVTeW5jKFwiL3Byb2MvbWVtaW5mb1wiLCBcInV0ZjhcIikubWF0Y2goL15NZW1BdmFpbGFibGU6XFxzKyhcXGQrKVxccytrQiQvbSk7XG4gICAgaWYgKG1hdGNoPy5bMV0pIHJldHVybiBOdW1iZXIobWF0Y2hbMV0pIC8gMTAyNCAvIDEwMjQ7XG4gIH0gY2F0Y2gge31cbiAgcmV0dXJuIGZyZWVtZW0oKSAvIDEwMjQgLyAxMDI0IC8gMTAyNDtcbn1cblxuLy8gdGhyZWFkIOyerOyCrOyaqShwcm9tcHQgY2FjaGUg6rOg7KCVKS4g64GE66m0IOq4sOyhtCBcIuunpCB0dXJuIOyDiCB0aHJlYWQgKyBoaXN0b3J5IGluamVjdFwiIOuPmeyekS5cbmNvbnN0IFRIUkVBRF9SRVVTRV9FTkFCTEVEID0gcHJvY2Vzcy5lbnYuUUdSSURfT1BFTkFJX1RIUkVBRF9SRVVTRSAhPT0gXCJmYWxzZVwiO1xuLy8g7KKM7ZGcIHdvcmtlciDqsIAgYnVzeSDsnbwg65WMIGZyZWUg66W8IOq4sOuLpOumrOuKlCDstZzrjIAg7Iuc6rCELiDstIjqs7wg7IucIOyDiCB0aHJlYWQg66GcIO2PtOuwsS5cbmNvbnN0IFJFVVNFX1dPUktFUl9XQUlUX01TID0gNV8wMDA7XG5jb25zdCBSRVVTRV9XT1JLRVJfUE9MTF9NUyA9IDUwO1xuXG4vLyB3b3JrZXJJZCDtlanshLE6IHRva2VuSWQg7JmAIHdvcmtlckluZGV4KDAuLjE5KSDrpbwg7ZWY64KY7J2YIOyViOyglSDsiKvsnpDroZwg7J247L2U65SpLlxuY29uc3QgT1BFTkFJX1dPUktFUl9JRF9TVFJJREUgPSAxMDA7XG5leHBvcnQgZnVuY3Rpb24gbWFrZU9wZW5BSVdvcmtlcklkKHRva2VuSWQ6IG51bWJlciwgd29ya2VySW5kZXg6IG51bWJlcik6IG51bWJlciB7XG4gIHJldHVybiB0b2tlbklkICogT1BFTkFJX1dPUktFUl9JRF9TVFJJREUgKyB3b3JrZXJJbmRleDtcbn1cblxuZnVuY3Rpb24gc2xlZXAobXM6IG51bWJlcik6IFByb21pc2U8dm9pZD4ge1xuICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHNldFRpbWVvdXQocmVzb2x2ZSwgbXMpKTtcbn1cblxuZnVuY3Rpb24gcXVvdGFUaHJlc2hvbGRFeGNlZWRlZE1lc3NhZ2UoXG4gIHByb3ZpZGVyOiBzdHJpbmcsXG4gIHRva2VuczogQXJyYXk8eyB0b2tlbk5hbWU6IHN0cmluZzsgdGhyZXNob2xkOiBudW1iZXIgfT4sXG4pOiBzdHJpbmcge1xuICBjb25zdCBkZXRhaWxzID0gdG9rZW5zXG4gICAgLm1hcCgodG9rZW4pID0+IGAke3Rva2VuLnRva2VuTmFtZX0gKHRocmVzaG9sZCAke3Rva2VuLnRocmVzaG9sZH0lKWApXG4gICAgLmpvaW4oXCIsIFwiKTtcbiAgcmV0dXJuIGRldGFpbHMubGVuZ3RoID4gMFxuICAgID8gYEFsbCAke3Byb3ZpZGVyfSB0b2tlbnMgZXhjZWVkZWQgcXVvdGEgdGhyZXNob2xkOiAke2RldGFpbHN9YFxuICAgIDogYEFsbCAke3Byb3ZpZGVyfSB0b2tlbnMgZXhjZWVkZWQgcXVvdGEgdGhyZXNob2xkYDtcbn1cblxudHlwZSBRdWV1ZUl0ZW0gPSB7XG4gIHJlc29sdmU6ICh3b3JrZXI6IENvZGV4QXBwU2VydmVyV29ya2VyKSA9PiB2b2lkO1xuICByZWplY3Q6IChlcnJvcjogRXJyb3IpID0+IHZvaWQ7XG4gIHRpbWVyOiBSZXR1cm5UeXBlPHR5cGVvZiBzZXRUaW1lb3V0PjtcbiAgYWJvcnRDbGVhbnVwPzogKCkgPT4gdm9pZDtcbiAgZXhjbHVkZWRUb2tlbklkczogU2V0PG51bWJlcj47XG59O1xuXG50eXBlIFRva2VuTWV0YWRhdGEgPSB7XG4gIG5hbWU6IHN0cmluZztcbiAgY3JlZGVudGlhbHM6IE9wZW5BSUNyZWRlbnRpYWxzO1xuICBxdW90YVRocmVzaG9sZD86IG51bWJlciB8IG51bGw7XG4gIHdlaWdodDogbnVtYmVyO1xuICBhY3RpdmU6IGJvb2xlYW47XG59O1xuXG50eXBlIFRva2VuRWxpZ2liaWxpdHkgPSB7XG4gIHJlYWR5QWN0aXZlVG9rZW5JZHM6IFNldDxudW1iZXI+O1xuICBlbGlnaWJsZVRva2VuSWRzOiBTZXQ8bnVtYmVyPjtcbiAgb3ZlclRocmVzaG9sZFRva2VuczogQXJyYXk8eyB0b2tlbk5hbWU6IHN0cmluZzsgdGhyZXNob2xkOiBudW1iZXIgfT47XG4gIHRocmVzaG9sZGVkVG9rZW5Db3VudDogbnVtYmVyO1xufTtcblxudHlwZSBSYXRlTGltaXRzQ2FjaGVFbnRyeSA9IE9wZW5BSVJhdGVMaW1pdHNXaXRoTWV0YSAmIHtcbiAgZ2VuZXJhdGlvbjogbnVtYmVyO1xufTtcblxuZXhwb3J0IGNsYXNzIE9wZW5BSURpc3BhdGNoZXIgaW1wbGVtZW50cyBQcm92aWRlckRpc3BhdGNoZXIge1xuICB3b3JrZXJQb29sID0gbmV3IE1hcDxudW1iZXIsIENvZGV4QXBwU2VydmVyV29ya2VyW10+KCk7XG4gIHRva2VuTWV0YWRhdGEgPSBuZXcgTWFwPG51bWJlciwgVG9rZW5NZXRhZGF0YT4oKTtcbiAgcXVldWU6IFF1ZXVlSXRlbVtdID0gW107XG4gIHJlYWRvbmx5IHBvb2xDb25maWc6IE9wZW5BSVdvcmtlclBvb2xDb25maWc7XG4gIHByaXZhdGUgcmVhZG9ubHkgcXVvdGFCbG9ja2VkVG9rZW5JZHMgPSBuZXcgU2V0PG51bWJlcj4oKTtcbiAgcHJpdmF0ZSByZWFkb25seSBzdGFydGluZ1Rva2VuSWRzID0gbmV3IFNldDxudW1iZXI+KCk7XG4gIHByaXZhdGUgcmVhZG9ubHkgcmF0ZUxpbWl0c0dlbmVyYXRpb25CeVRva2VuID0gbmV3IE1hcDxudW1iZXIsIG51bWJlcj4oKTtcbiAgcHJpdmF0ZSByZWFkb25seSB3ZWlnaHRlZFNlbGVjdG9yID0gbmV3IFNtb290aFdlaWdodGVkUm91bmRSb2JpbigpO1xuICBwcml2YXRlIHJlYWRvbmx5IHdvcmtlckN1cnNvckJ5VG9rZW4gPSBuZXcgTWFwPG51bWJlciwgbnVtYmVyPigpO1xuICBwcml2YXRlIHJlYWRvbmx5IGdldEhvc3RBdmFpbGFibGVHaUI6ICgpID0+IG51bWJlcjtcbiAgcHJpdmF0ZSBkcmFpbmluZyA9IGZhbHNlO1xuICBwcml2YXRlIGRyYWluQWdhaW4gPSBmYWxzZTtcbiAgcHJpdmF0ZSBzY2FsZXJUaW1lcjogUmV0dXJuVHlwZTx0eXBlb2Ygc2V0SW50ZXJ2YWw+IHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgc2NhbGluZ1Byb21pc2U6IFByb21pc2U8dm9pZD4gfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBsYXN0UmVxdWVzdEF0ID0gRGF0ZS5ub3coKTtcbiAgcHJpdmF0ZSBzdG9wcGVkID0gZmFsc2U7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcG9vbENvbmZpZzogT3BlbkFJV29ya2VyUG9vbENvbmZpZyA9IHJlc29sdmVPcGVuQUlXb3JrZXJQb29sQ29uZmlnKCksXG4gICAgZ2V0SG9zdEF2YWlsYWJsZUdpQjogKCkgPT4gbnVtYmVyID0gcmVhZEhvc3RBdmFpbGFibGVHaUIsXG4gICkge1xuICAgIHRoaXMucG9vbENvbmZpZyA9IHBvb2xDb25maWc7XG4gICAgdGhpcy5nZXRIb3N0QXZhaWxhYmxlR2lCID0gZ2V0SG9zdEF2YWlsYWJsZUdpQjtcbiAgfVxuXG4gIGFzeW5jIHN0YXJ0KCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRoaXMuc3RvcHBlZCA9IGZhbHNlO1xuICAgIGNvbnN0IHsgcm93cyB9ID0gYXdhaXQgVG9rZW5Nb2RlbC5maW5kTWFueShcIkFcIik7XG4gICAgY29uc3Qgb3BlbmFpVG9rZW5zID0gcm93cy5maWx0ZXIoKHQpID0+IHQucHJvdmlkZXIgPT09IFwib3BlbmFpXCIpO1xuICAgIGxvZ2dlci5pbmZvKFxuICAgICAgdGhpcy5wb29sQ29uZmlnLmF1dG9zY2FsZVxuICAgICAgICA/IGBzdGFydGluZyAke29wZW5haVRva2Vucy5sZW5ndGh9IG9wZW5haSB0b2tlbnMgKCR7dGhpcy5wb29sQ29uZmlnLm1pbldvcmtlcnNQZXJUb2tlbn0tJHt0aGlzLnBvb2xDb25maWcubWF4V29ya2Vyc1BlclRva2VufSB3b3JrZXJzIGVhY2gsIGF1dG9zY2FsZSlgXG4gICAgICAgIDogYHN0YXJ0aW5nICR7b3BlbmFpVG9rZW5zLmxlbmd0aH0gb3BlbmFpIHRva2VucyAoJHt0aGlzLnBvb2xDb25maWcubWluV29ya2Vyc1BlclRva2VufSB3b3JrZXJzIGVhY2gpYCxcbiAgICApO1xuXG4gICAgYXdhaXQgUHJvbWlzZS5hbGxTZXR0bGVkKFxuICAgICAgb3BlbmFpVG9rZW5zLm1hcChhc3luYyAodCkgPT4ge1xuICAgICAgICBhd2FpdCB0aGlzLnNwYXduV29ya2VycyhcbiAgICAgICAgICB0LmlkLFxuICAgICAgICAgIHQubmFtZSxcbiAgICAgICAgICB0LmNyZWRlbnRpYWxzIGFzIE9wZW5BSUNyZWRlbnRpYWxzLFxuICAgICAgICAgIHQucXVvdGFfdGhyZXNob2xkLFxuICAgICAgICAgIHQud2VpZ2h0LFxuICAgICAgICApO1xuICAgICAgICBpZiAoIXQuYWN0aXZlKSB0aGlzLm9uVG9rZW5EZWFjdGl2YXRlZCh0LmlkKTtcbiAgICAgIH0pLFxuICAgICk7XG5cbiAgICAvLyBhdXRvc2NhbGUgb2Zm64+EIGZpeGVkIG1pbuydmCBoZWFsdGggbWFpbnRlbmFuY2XripQg6rOE7IaNIO2VhOyalO2VmOuLpC5cbiAgICB0aGlzLnNjYWxlclRpbWVyID0gc2V0SW50ZXJ2YWwoXG4gICAgICAoKSA9PiB0aGlzLnJlcXVlc3RBdXRvc2NhbGVFdmFsdWF0aW9uKCksXG4gICAgICB0aGlzLnBvb2xDb25maWcuc2NhbGVJbnRlcnZhbE1zLFxuICAgICk7XG4gICAgdGhpcy5zY2FsZXJUaW1lci51bnJlZj8uKCk7XG4gIH1cblxuICBhc3luYyBzdG9wKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRoaXMuc3RvcHBlZCA9IHRydWU7XG4gICAgaWYgKHRoaXMuc2NhbGVyVGltZXIpIHtcbiAgICAgIGNsZWFySW50ZXJ2YWwodGhpcy5zY2FsZXJUaW1lcik7XG4gICAgICB0aGlzLnNjYWxlclRpbWVyID0gbnVsbDtcbiAgICB9XG4gICAgYXdhaXQgdGhpcy5zY2FsaW5nUHJvbWlzZT8uY2F0Y2goKCkgPT4ge30pO1xuICAgIHRoaXMucmVqZWN0QWxsUXVldWVkKFwiRElTUEFUQ0hFUl9TSFVURE9XTlwiKTtcbiAgICBjb25zdCBraWxscyA9IFsuLi50aGlzLndvcmtlclBvb2wudmFsdWVzKCldLmZsYXQoKS5tYXAoKHcpID0+IHcua2lsbCgpKTtcbiAgICBhd2FpdCBQcm9taXNlLmFsbFNldHRsZWQoa2lsbHMpO1xuICAgIGZvciAoY29uc3QgaWQgb2YgdGhpcy50b2tlbk1ldGFkYXRhLmtleXMoKSkgdGhpcy53ZWlnaHRlZFNlbGVjdG9yLnJlbW92ZVRva2VuKGlkKTtcbiAgICB0aGlzLndvcmtlclBvb2wuY2xlYXIoKTtcbiAgICB0aGlzLnRva2VuTWV0YWRhdGEuY2xlYXIoKTtcbiAgICB0aGlzLndvcmtlckN1cnNvckJ5VG9rZW4uY2xlYXIoKTtcbiAgICB0aGlzLndlaWdodGVkU2VsZWN0b3IucmVzZXRTY29yZXMoKTtcbiAgICB0aGlzLnJhdGVMaW1pdHNDYWNoZS5jbGVhcigpO1xuICAgIHRoaXMucmF0ZUxpbWl0c0dlbmVyYXRpb25CeVRva2VuLmNsZWFyKCk7XG4gICAgdGhpcy5xdW90YUJsb2NrZWRUb2tlbklkcy5jbGVhcigpO1xuICAgIHRoaXMuc3RhcnRpbmdUb2tlbklkcy5jbGVhcigpO1xuICB9XG5cbiAgLy8g4pSA4pSAIFRva2VuIGV2ZW50cyAoZnJvbSBUb2tlblN1YnNjcmliZXIpIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIGFzeW5jIG9uVG9rZW5BZGRlZChcbiAgICBpZDogbnVtYmVyLFxuICAgIG5hbWU6IHN0cmluZyxcbiAgICBjcmVkZW50aWFsczogT3BlbkFJQ3JlZGVudGlhbHMsXG4gICAgcXVvdGFUaHJlc2hvbGQ/OiBudW1iZXIgfCBudWxsLFxuICAgIHdlaWdodCA9IDEsXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRoaXMucXVvdGFCbG9ja2VkVG9rZW5JZHMuZGVsZXRlKGlkKTtcbiAgICB0aGlzLmludmFsaWRhdGVSYXRlTGltaXRzQ2FjaGUoaWQpO1xuICAgIHRoaXMuc2V0VG9rZW5NZXRhZGF0YShpZCwgbmFtZSwgY3JlZGVudGlhbHMsIHF1b3RhVGhyZXNob2xkLCB3ZWlnaHQpO1xuICAgIGlmICh0aGlzLndvcmtlclBvb2wuaGFzKGlkKSkgcmV0dXJuO1xuICAgIGF3YWl0IHRoaXMuc3Bhd25Xb3JrZXJzKGlkLCBuYW1lLCBjcmVkZW50aWFscywgcXVvdGFUaHJlc2hvbGQsIHdlaWdodCk7XG4gIH1cblxuICBhc3luYyBvblRva2VuUmVtb3ZlZChpZDogbnVtYmVyKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3Qgd29ya2VycyA9IHRoaXMud29ya2VyUG9vbC5nZXQoaWQpID8/IFtdO1xuICAgIGNvbnN0IHRva2VuTmFtZSA9IHdvcmtlcnNbMF0/LnRva2VuTmFtZTtcbiAgICB0aGlzLndvcmtlclBvb2wuZGVsZXRlKGlkKTtcbiAgICB0aGlzLnRva2VuTWV0YWRhdGEuZGVsZXRlKGlkKTtcbiAgICB0aGlzLndlaWdodGVkU2VsZWN0b3IucmVtb3ZlVG9rZW4oaWQpO1xuICAgIHRoaXMud29ya2VyQ3Vyc29yQnlUb2tlbi5kZWxldGUoaWQpO1xuICAgIHRoaXMuaW52YWxpZGF0ZVJhdGVMaW1pdHNDYWNoZShpZCk7XG4gICAgdGhpcy5xdW90YUJsb2NrZWRUb2tlbklkcy5kZWxldGUoaWQpO1xuICAgIGF3YWl0IFByb21pc2UuYWxsU2V0dGxlZCh3b3JrZXJzLm1hcCgodykgPT4gdy5raWxsKCkpKTtcbiAgICBpZiAoIXRoaXMuaGFzQWN0aXZlVG9rZW5DYW5kaWRhdGUobmV3IFNldCgpKSkge1xuICAgICAgdGhpcy5yZWplY3RBbGxRdWV1ZWQoXCJOT19PUEVOQUlfV09SS0VSU1wiKTtcbiAgICB9XG4gICAgaWYgKHdvcmtlcnMubGVuZ3RoID4gMCkge1xuICAgICAgY29uc3QgbGFiZWwgPSB0b2tlbk5hbWUgPz8gYHRva2VuICR7aWR9YDtcbiAgICAgIGxvZ2dlci5pbmZvKGB3b3JrZXJzIHJlbW92ZWQ6ICR7bGFiZWx9ICgke3dvcmtlcnMubGVuZ3RofSlgKTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBvblRva2VuVXBkYXRlZChcbiAgICBpZDogbnVtYmVyLFxuICAgIG5hbWU6IHN0cmluZyxcbiAgICBjcmVkZW50aWFsczogT3BlbkFJQ3JlZGVudGlhbHMsXG4gICAgcXVvdGFUaHJlc2hvbGQ/OiBudW1iZXIgfCBudWxsLFxuICAgIHdlaWdodCA9IDEsXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGV4aXN0aW5nID0gdGhpcy53b3JrZXJQb29sLmdldChpZCkgPz8gW107XG4gICAgY29uc3QgdGhyZXNob2xkQ2hhbmdlZCA9IHRoaXMuZ2V0UXVvdGFUaHJlc2hvbGQoaWQpICE9PSBxdW90YVRocmVzaG9sZDtcbiAgICBpZiAodGhyZXNob2xkQ2hhbmdlZCkgdGhpcy5xdW90YUJsb2NrZWRUb2tlbklkcy5kZWxldGUoaWQpO1xuICAgIHRoaXMuc2V0VG9rZW5NZXRhZGF0YShpZCwgbmFtZSwgY3JlZGVudGlhbHMsIHF1b3RhVGhyZXNob2xkLCB3ZWlnaHQpO1xuXG4gICAgaWYgKGV4aXN0aW5nLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhpcy5pbnZhbGlkYXRlUmF0ZUxpbWl0c0NhY2hlKGlkKTtcbiAgICAgIGF3YWl0IHRoaXMuc3Bhd25Xb3JrZXJzKGlkLCBuYW1lLCBjcmVkZW50aWFscywgcXVvdGFUaHJlc2hvbGQsIHdlaWdodCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKGV4aXN0aW5nLmV2ZXJ5KCh3KSA9PiB3LmNhblJldXNlRm9yVG9rZW4obmFtZSwgY3JlZGVudGlhbHMpKSkge1xuICAgICAgZXhpc3RpbmcuZm9yRWFjaCgodykgPT4gdy51cGRhdGVUb2tlblN0YXRlKG5hbWUsIGNyZWRlbnRpYWxzKSk7XG4gICAgICBsb2dnZXIuaW5mbyhgd29ya2VycyB1cGRhdGVkIGluLXBsYWNlOiAke25hbWV9YCk7XG4gICAgICB0aGlzLnJlcXVlc3REcmFpblF1ZXVlKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy53b3JrZXJQb29sLmRlbGV0ZShpZCk7XG4gICAgdGhpcy5pbnZhbGlkYXRlUmF0ZUxpbWl0c0NhY2hlKGlkKTtcbiAgICB0aGlzLnF1b3RhQmxvY2tlZFRva2VuSWRzLmRlbGV0ZShpZCk7XG4gICAgYXdhaXQgUHJvbWlzZS5hbGxTZXR0bGVkKGV4aXN0aW5nLm1hcCgodykgPT4gdy5raWxsKCkpKTtcbiAgICBhd2FpdCB0aGlzLnNwYXduV29ya2VycyhpZCwgbmFtZSwgY3JlZGVudGlhbHMsIHF1b3RhVGhyZXNob2xkLCB3ZWlnaHQpO1xuICB9XG5cbiAgb25Ub2tlbkRlYWN0aXZhdGVkKGlkOiBudW1iZXIpOiB2b2lkIHtcbiAgICBjb25zdCB3b3JrZXJzID0gdGhpcy53b3JrZXJQb29sLmdldChpZCkgPz8gW107XG4gICAgY29uc3QgdG9rZW5OYW1lID0gd29ya2Vyc1swXT8udG9rZW5OYW1lO1xuICAgIGNvbnN0IG1ldGFkYXRhID0gdGhpcy50b2tlbk1ldGFkYXRhLmdldChpZCk7XG4gICAgaWYgKG1ldGFkYXRhPy5hY3RpdmUpIHRoaXMudG9rZW5NZXRhZGF0YS5zZXQoaWQsIHsgLi4ubWV0YWRhdGEsIGFjdGl2ZTogZmFsc2UgfSk7XG4gICAgdGhpcy5xdW90YUJsb2NrZWRUb2tlbklkcy5kZWxldGUoaWQpO1xuICAgIGNvbnN0IGNoYW5nZWQgPSB3b3JrZXJzLnNvbWUoKHdvcmtlcikgPT4gd29ya2VyLmFjdGl2ZSk7XG4gICAgd29ya2Vycy5mb3JFYWNoKCh3KSA9PiB7XG4gICAgICB3LmFjdGl2ZSA9IGZhbHNlO1xuICAgIH0pO1xuICAgIGlmIChjaGFuZ2VkKSB0aGlzLndlaWdodGVkU2VsZWN0b3IucmVzZXRTY29yZXMoKTtcbiAgICBpZiAoIXRoaXMuaGFzQWN0aXZlVG9rZW5DYW5kaWRhdGUobmV3IFNldCgpKSkge1xuICAgICAgdGhpcy5yZWplY3RBbGxRdWV1ZWQoXCJOT19BQ1RJVkVfV09SS0VSU1wiKTtcbiAgICB9XG4gICAgY29uc3QgbGFiZWwgPSB0b2tlbk5hbWUgPz8gYHRva2VuICR7aWR9YDtcbiAgICBsb2dnZXIuaW5mbyhgd29ya2VycyBkZWFjdGl2YXRlZDogJHtsYWJlbH1gKTtcbiAgfVxuXG4gIG9uVG9rZW5BY3RpdmF0ZWQoaWQ6IG51bWJlcik6IHZvaWQge1xuICAgIGNvbnN0IHdvcmtlcnMgPSB0aGlzLndvcmtlclBvb2wuZ2V0KGlkKSA/PyBbXTtcbiAgICBjb25zdCB0b2tlbk5hbWUgPSB3b3JrZXJzWzBdPy50b2tlbk5hbWU7XG4gICAgY29uc3QgbWV0YWRhdGEgPSB0aGlzLnRva2VuTWV0YWRhdGEuZ2V0KGlkKTtcbiAgICBpZiAobWV0YWRhdGEgJiYgIW1ldGFkYXRhLmFjdGl2ZSkgdGhpcy50b2tlbk1ldGFkYXRhLnNldChpZCwgeyAuLi5tZXRhZGF0YSwgYWN0aXZlOiB0cnVlIH0pO1xuICAgIGNvbnN0IGNoYW5nZWQgPSB3b3JrZXJzLnNvbWUoKHdvcmtlcikgPT4gIXdvcmtlci5hY3RpdmUpO1xuICAgIHdvcmtlcnMuZm9yRWFjaCgodykgPT4ge1xuICAgICAgdy5hY3RpdmUgPSB0cnVlO1xuICAgIH0pO1xuICAgIGlmIChjaGFuZ2VkKSB0aGlzLndlaWdodGVkU2VsZWN0b3IucmVzZXRTY29yZXMoKTtcbiAgICB0aGlzLnJlcXVlc3REcmFpblF1ZXVlKCk7XG4gICAgY29uc3QgbGFiZWwgPSB0b2tlbk5hbWUgPz8gYHRva2VuICR7aWR9YDtcbiAgICBsb2dnZXIuaW5mbyhgd29ya2VycyBhY3RpdmF0ZWQ6ICR7bGFiZWx9YCk7XG4gIH1cblxuICBhc3luYyByZXBsYWNlVG9rZW5zKFxuICAgIHJvd3M6IEFycmF5PHtcbiAgICAgIGlkOiBudW1iZXI7XG4gICAgICBuYW1lOiBzdHJpbmc7XG4gICAgICBjcmVkZW50aWFsczogT3BlbkFJQ3JlZGVudGlhbHM7XG4gICAgICBxdW90YVRocmVzaG9sZD86IG51bWJlciB8IG51bGw7XG4gICAgICB3ZWlnaHQ6IG51bWJlcjtcbiAgICB9PixcbiAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgbmV4dCA9IG5ldyBTZXQocm93cy5tYXAoKHIpID0+IHIuaWQpKTtcbiAgICBmb3IgKGNvbnN0IGlkIG9mIEFycmF5LmZyb20odGhpcy53b3JrZXJQb29sLmtleXMoKSkpIHtcbiAgICAgIGlmICghbmV4dC5oYXMoaWQpKSBhd2FpdCB0aGlzLm9uVG9rZW5SZW1vdmVkKGlkKTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IHJvdyBvZiByb3dzKSB7XG4gICAgICBpZiAodGhpcy53b3JrZXJQb29sLmhhcyhyb3cuaWQpKSB7XG4gICAgICAgIGF3YWl0IHRoaXMub25Ub2tlblVwZGF0ZWQoXG4gICAgICAgICAgcm93LmlkLFxuICAgICAgICAgIHJvdy5uYW1lLFxuICAgICAgICAgIHJvdy5jcmVkZW50aWFscyxcbiAgICAgICAgICByb3cucXVvdGFUaHJlc2hvbGQsXG4gICAgICAgICAgcm93LndlaWdodCxcbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGF3YWl0IHRoaXMub25Ub2tlbkFkZGVkKHJvdy5pZCwgcm93Lm5hbWUsIHJvdy5jcmVkZW50aWFscywgcm93LnF1b3RhVGhyZXNob2xkLCByb3cud2VpZ2h0KTtcbiAgICAgIH1cbiAgICAgIHRoaXMub25Ub2tlbkFjdGl2YXRlZChyb3cuaWQpO1xuICAgIH1cbiAgfVxuXG4gIC8vIOKUgOKUgCBHZW5lcmF0ZSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuICBhc3luYyBnZW5lcmF0ZShyZXE6IEdlbmVyYXRlUmVxdWVzdCk6IFByb21pc2U8R2VuZXJhdGVSZXN1bHQ+IHtcbiAgICB0aGlzLmxhc3RSZXF1ZXN0QXQgPSBEYXRlLm5vdygpO1xuICAgIGNvbnN0IGV4Y2x1ZGVkVG9rZW5JZHMgPSBuZXcgU2V0PG51bWJlcj4oKTtcbiAgICAvLyB0aHJlYWQg7J6s7IKs7JqpIOqyveuhnDog7KKM7ZGcIHdvcmtlciDrpbwg7KCQ7Jyg7ZW0IOq4sOyhtCB0aHJlYWQg7JeQIHR1cm4g66eMIOyLpO2WiS5cbiAgICBjb25zdCByZXVzZVdvcmtlciA9IGF3YWl0IHRoaXMuYWNxdWlyZVJldXNlV29ya2VyKHJlcSwgZXhjbHVkZWRUb2tlbklkcyk7XG4gICAgaWYgKHJldXNlV29ya2VyKSB7XG4gICAgICBsb2dnZXIuaW5mbyhcbiAgICAgICAgYOKGuyAke3JldXNlV29ya2VyLnRva2VuTmFtZX1bJHtyZXVzZVdvcmtlci50b2tlbklkfV0gKHJldXNlIHRocmVhZCwgJHtyZXEubW9kZWx9KWAsXG4gICAgICApO1xuICAgICAgcmV0dXJuIHRoaXMuZXhlY3V0ZUFuZFJlbGVhc2UocmV1c2VXb3JrZXIsICh3KSA9PlxuICAgICAgICB0aGlzLmV4ZWN1dGVUdXJuKHcsIHJlcSwgcmVxLnJldXNlIS50aHJlYWRJZCksXG4gICAgICApO1xuICAgIH1cblxuICAgIGNvbnN0IHdvcmtlciA9IGF3YWl0IHRoaXMuYWNxdWlyZUlkbGVXb3JrZXIoZXhjbHVkZWRUb2tlbklkcyk7XG4gICAgaWYgKHdvcmtlcikge1xuICAgICAgbG9nZ2VyLmluZm8oYOKGkiAke3dvcmtlci50b2tlbk5hbWV9WyR7d29ya2VyLnRva2VuSWR9XSAobW9kZWw6ICR7cmVxLm1vZGVsfSlgKTtcbiAgICAgIHJldHVybiB0aGlzLmV4ZWN1dGVBbmRSZWxlYXNlKHdvcmtlciwgKHcpID0+IHRoaXMuZXhlY3V0ZVR1cm4odywgcmVxKSk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmVucXVldWUoKHcpID0+IHtcbiAgICAgIGxvZ2dlci5pbmZvKGDihpIgJHt3LnRva2VuTmFtZX1bJHt3LnRva2VuSWR9XSAobW9kZWw6ICR7cmVxLm1vZGVsfSwgcXVldWVkKWApO1xuICAgICAgcmV0dXJuIHRoaXMuZXhlY3V0ZVR1cm4odywgcmVxKTtcbiAgICB9LCBleGNsdWRlZFRva2VuSWRzKTtcbiAgfVxuXG4gIGFzeW5jIGdlbmVyYXRlU3RyZWFtKHJlcTogR2VuZXJhdGVSZXF1ZXN0LCBjYjogR2VuZXJhdGVTdHJlYW1DYWxsYmFja3MpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0aGlzLmxhc3RSZXF1ZXN0QXQgPSBEYXRlLm5vdygpO1xuICAgIC8vIOydtOuvuOyngCDsg53shLHsnYAgbm9uLXN0cmVhbSDsoITsmqkoUjIpOiBjb2RleCDqsIAg7J2066+47KeAIOuNuO2DgOulvCDso7zsp4Ag7JWK6rOgIOyZhOyEsSBiYXNlNjQg66W8XG4gICAgLy8g7ZWcIOuyiOyXkCDspIDri6QuIOyKpO2KuOumrOuwjSDqsr3roZzroZwg7J2066+47KeAIOyalOyyreydtCDsmKTrqbQg66qF7Iuc7KCBIOyXkOufrC5cbiAgICBpZiAocmVxLmltYWdlR2VuZXJhdGlvbikge1xuICAgICAgdGhyb3cgbmV3IEltYWdlR2VuZXJhdGlvbkVycm9yKFxuICAgICAgICBcImdhdGVcIixcbiAgICAgICAgXCJpbWFnZSBnZW5lcmF0aW9uIGlzIG5vdCBzdXBwb3J0ZWQgb24gdGhlIHN0cmVhbWluZyBwYXRoXCIsXG4gICAgICApO1xuICAgIH1cbiAgICBjb25zdCBleGNsdWRlZFRva2VuSWRzID0gbmV3IFNldDxudW1iZXI+KCk7XG4gICAgY29uc3QgcmV1c2VXb3JrZXIgPSBhd2FpdCB0aGlzLmFjcXVpcmVSZXVzZVdvcmtlcihyZXEsIGV4Y2x1ZGVkVG9rZW5JZHMpO1xuICAgIGlmIChyZXVzZVdvcmtlcikge1xuICAgICAgbG9nZ2VyLmluZm8oYOKGuyAke3JldXNlV29ya2VyLnRva2VuTmFtZX1bJHtyZXVzZVdvcmtlci50b2tlbklkfV0gKHJldXNlIHRocmVhZCwgW3N0cmVhbV0pYCk7XG4gICAgICByZXR1cm4gdGhpcy5leGVjdXRlQW5kUmVsZWFzZShyZXVzZVdvcmtlciwgKHcpID0+XG4gICAgICAgIHRoaXMuZXhlY3V0ZVN0cmVhbVR1cm4odywgcmVxLCBjYiwgcmVxLnJldXNlIS50aHJlYWRJZCksXG4gICAgICApO1xuICAgIH1cblxuICAgIGNvbnN0IHdvcmtlciA9IGF3YWl0IHRoaXMuYWNxdWlyZUlkbGVXb3JrZXIoZXhjbHVkZWRUb2tlbklkcyk7XG4gICAgaWYgKHdvcmtlcikge1xuICAgICAgbG9nZ2VyLmluZm8oYOKGkiAke3dvcmtlci50b2tlbk5hbWV9WyR7d29ya2VyLnRva2VuSWR9XSAobW9kZWw6ICR7cmVxLm1vZGVsfSwgW3N0cmVhbV0pYCk7XG4gICAgICByZXR1cm4gdGhpcy5leGVjdXRlQW5kUmVsZWFzZSh3b3JrZXIsICh3KSA9PiB0aGlzLmV4ZWN1dGVTdHJlYW1UdXJuKHcsIHJlcSwgY2IpKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuZW5xdWV1ZSgodykgPT4ge1xuICAgICAgbG9nZ2VyLmluZm8oYOKGkiAke3cudG9rZW5OYW1lfVske3cudG9rZW5JZH1dIChtb2RlbDogJHtyZXEubW9kZWx9LCBbc3RyZWFtXSwgcXVldWVkKWApO1xuICAgICAgcmV0dXJuIHRoaXMuZXhlY3V0ZVN0cmVhbVR1cm4odywgcmVxLCBjYik7XG4gICAgfSwgZXhjbHVkZWRUb2tlbklkcyk7XG4gIH1cblxuICAvLyByZXVzZSDsooztkZzqsIAg7Jyg7Zqo7ZWY66m0IOq3uCB3b3JrZXIg66W8IGJ1c3kg7KCQ7Jyg7ZW0IOuwmO2ZmC4g7JeG6rGw64KYIO2PtOuwsSDrjIDsg4HsnbTrqbQgbnVsbC5cbiAgLy8g7Y+067CxIOyCrOycoDog6riw64qlIG9mZiAvIOyijO2RnCDsl4bsnYwgLyB3b3JrZXIg67aA7J6swrfso73snYwgLyBlcG9jaCDrtojsnbzsuZgocmVzdGFydCkgLyB0aHJlYWQg7IaM66m4IC9cbiAgLy8gICAgICAgICAgICBidXN5IOuMgOq4sCDtg4DsnoTslYTsm4MuIG51bGwg67CY7ZmYIOyLnCDtmLjstpzrtoDripQg7IOIIHRocmVhZCDqsr3roZzroZwg7KeE7ZaJLlxuICBhc3luYyBhY3F1aXJlUmV1c2VXb3JrZXIoXG4gICAgcmVxOiBHZW5lcmF0ZVJlcXVlc3QsXG4gICAgZXhjbHVkZWRUb2tlbklkcyA9IG5ldyBTZXQ8bnVtYmVyPigpLFxuICApOiBQcm9taXNlPENvZGV4QXBwU2VydmVyV29ya2VyIHwgbnVsbD4ge1xuICAgIC8vIOydtOuvuOyngCDsmpTssq3snYAg7ZWt7IOBIGNvbGQgdGhyZWFkKFI4KTog7J6s7IKs7JqpIOyijO2RnOqwgCDsnojslrTrj4Qg6rG064SI65u064ukLlxuICAgIC8vIGJhc2U2NCDqsIAgdGhyZWFkIOuplOuqqOumrMK37LqQ7IucIHByZWZpeCDsl5Ag7IOB7KO87ZWY64qUIOqyg+ydhCDrp4nripTri6QuXG4gICAgaWYgKHJlcS5pbWFnZUdlbmVyYXRpb24pIHJldHVybiBudWxsO1xuICAgIGlmICghVEhSRUFEX1JFVVNFX0VOQUJMRUQgfHwgIXJlcS5yZXVzZSkgcmV0dXJuIG51bGw7XG4gICAgY29uc3QgeyB3b3JrZXJJZCwgdGhyZWFkSWQsIGVwb2NoIH0gPSByZXEucmV1c2U7XG5cbiAgICBjb25zdCB3b3JrZXIgPSB0aGlzLmZpbmRXb3JrZXJCeUlkKHdvcmtlcklkKTtcbiAgICBpZiAoIXdvcmtlciB8fCAhd29ya2VyLmlzUmVhZHkgfHwgIXdvcmtlci5hY3RpdmUpIHJldHVybiBudWxsO1xuICAgIGlmICh3b3JrZXIuZXBvY2ggIT09IGVwb2NoKSByZXR1cm4gbnVsbDtcbiAgICBpZiAoIXdvcmtlci5oYXNUaHJlYWQodGhyZWFkSWQpKSByZXR1cm4gbnVsbDtcbiAgICBjb25zdCBxdW90YU1ldGFkYXRhID0gdGhpcy50b2tlbk1ldGFkYXRhLmdldCh3b3JrZXIudG9rZW5JZCk7XG4gICAgaWYgKCEoYXdhaXQgdGhpcy5pc1Rva2VuUXVvdGFFbGlnaWJsZSh3b3JrZXIudG9rZW5JZCwgd29ya2VyLnRva2VuTmFtZSwgZXhjbHVkZWRUb2tlbklkcykpKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgaWYgKFxuICAgICAgIXdvcmtlci5pc1JlYWR5IHx8XG4gICAgICAhd29ya2VyLmFjdGl2ZSB8fFxuICAgICAgdGhpcy50b2tlbk1ldGFkYXRhLmdldCh3b3JrZXIudG9rZW5JZCkgIT09IHF1b3RhTWV0YWRhdGEgfHxcbiAgICAgIHRoaXMucXVvdGFCbG9ja2VkVG9rZW5JZHMuaGFzKHdvcmtlci50b2tlbklkKVxuICAgICkge1xuICAgICAgaWYgKHRoaXMucXVvdGFCbG9ja2VkVG9rZW5JZHMuaGFzKHdvcmtlci50b2tlbklkKSkge1xuICAgICAgICBleGNsdWRlZFRva2VuSWRzLmFkZCh3b3JrZXIudG9rZW5JZCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBjb25zdCBkZWFkbGluZSA9IERhdGUubm93KCkgKyBSRVVTRV9XT1JLRVJfV0FJVF9NUztcbiAgICBmb3IgKDs7KSB7XG4gICAgICAvLyByZXN0YXJ0KGVwb2NoIOuzgOqyvSkgLyB0aHJlYWQg7IaM66m47J20IOuMgOq4sCDspJHsl5Ag67Cc7IOd7ZWY66m0IO2PtOuwsS5cbiAgICAgIGlmIChcbiAgICAgICAgIXdvcmtlci5pc1JlYWR5IHx8XG4gICAgICAgICF3b3JrZXIuYWN0aXZlIHx8XG4gICAgICAgIHdvcmtlci5lcG9jaCAhPT0gZXBvY2ggfHxcbiAgICAgICAgIXdvcmtlci5oYXNUaHJlYWQodGhyZWFkSWQpIHx8XG4gICAgICAgIHRoaXMudG9rZW5NZXRhZGF0YS5nZXQod29ya2VyLnRva2VuSWQpICE9PSBxdW90YU1ldGFkYXRhIHx8XG4gICAgICAgIHRoaXMucXVvdGFCbG9ja2VkVG9rZW5JZHMuaGFzKHdvcmtlci50b2tlbklkKVxuICAgICAgKSB7XG4gICAgICAgIGlmICh0aGlzLnF1b3RhQmxvY2tlZFRva2VuSWRzLmhhcyh3b3JrZXIudG9rZW5JZCkpIHtcbiAgICAgICAgICBleGNsdWRlZFRva2VuSWRzLmFkZCh3b3JrZXIudG9rZW5JZCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG4gICAgICBpZiAod29ya2VyLnRyeUFjcXVpcmVUdXJuKCkpIHJldHVybiB3b3JrZXI7XG4gICAgICBpZiAoRGF0ZS5ub3coKSA+PSBkZWFkbGluZSkgcmV0dXJuIG51bGw7XG4gICAgICBhd2FpdCBzbGVlcChSRVVTRV9XT1JLRVJfUE9MTF9NUyk7XG4gICAgfVxuICB9XG5cbiAgZmluZFdvcmtlckJ5SWQod29ya2VySWQ6IG51bWJlcik6IENvZGV4QXBwU2VydmVyV29ya2VyIHwgbnVsbCB7XG4gICAgZm9yIChjb25zdCB3b3JrZXJzIG9mIHRoaXMud29ya2VyUG9vbC52YWx1ZXMoKSkge1xuICAgICAgZm9yIChjb25zdCB3IG9mIHdvcmtlcnMpIHtcbiAgICAgICAgaWYgKG1ha2VPcGVuQUlXb3JrZXJJZCh3LnRva2VuSWQsIHcud29ya2VySW5kZXgpID09PSB3b3JrZXJJZCkgcmV0dXJuIHc7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgYXN5bmMgaW50ZXJydXB0V29ya2VyVHVybih0aHJlYWRJZDogc3RyaW5nLCB0dXJuSWQ6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGFsbFdvcmtlcnMgPSBbLi4udGhpcy53b3JrZXJQb29sLnZhbHVlcygpXS5mbGF0KCkuZmlsdGVyKCh3KSA9PiB3LmlzUmVhZHkpO1xuICAgIGF3YWl0IFByb21pc2UuYWxsU2V0dGxlZChhbGxXb3JrZXJzLm1hcCgodykgPT4gdy5pbnRlcnJ1cHRUdXJuKHRocmVhZElkLCB0dXJuSWQpKSk7XG4gIH1cblxuICAvLyDilIDilIAgV29ya2VyIHNlbGVjdGlvbiDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcbiAgLy8gUXVvdGEtZWxpZ2libGUgaWRsZSB0b2tlbuydhCB3ZWlnaHTroZwg6rOg66W4IOuSpCwg6re4IHRva2VuIOyViOyXkOyEnCB3b3JrZXLrpbwg7Iic7ZmY7ZWc64ukLlxuICBhc3luYyBhY3F1aXJlSWRsZVdvcmtlcihcbiAgICBleGNsdWRlZFRva2VuSWRzID0gbmV3IFNldDxudW1iZXI+KCksXG4gICk6IFByb21pc2U8Q29kZXhBcHBTZXJ2ZXJXb3JrZXIgfCBudWxsPiB7XG4gICAgY29uc3QgZWxpZ2liaWxpdHkgPSBhd2FpdCB0aGlzLnJlc29sdmVUb2tlbkVsaWdpYmlsaXR5KGV4Y2x1ZGVkVG9rZW5JZHMpO1xuICAgIGlmIChlbGlnaWJpbGl0eS5yZWFkeUFjdGl2ZVRva2VuSWRzLnNpemUgPT09IDApIHJldHVybiBudWxsO1xuICAgIGlmIChlbGlnaWJpbGl0eS5lbGlnaWJsZVRva2VuSWRzLnNpemUgPT09IDApIHRoaXMudGhyb3dRdW90YVRocmVzaG9sZEV4Y2VlZGVkKGVsaWdpYmlsaXR5KTtcblxuICAgIGNvbnN0IHdvcmtlcnNCeVRva2VuID0gbmV3IE1hcDxudW1iZXIsIENvZGV4QXBwU2VydmVyV29ya2VyW10+KCk7XG4gICAgZm9yIChjb25zdCB3b3JrZXIgb2YgdGhpcy5nZXRBbGxSZWFkeUFjdGl2ZVdvcmtlcnMoKSkge1xuICAgICAgaWYgKCFlbGlnaWJpbGl0eS5lbGlnaWJsZVRva2VuSWRzLmhhcyh3b3JrZXIudG9rZW5JZCkgfHwgIXdvcmtlci5oYXNDYXBhY2l0eSkgY29udGludWU7XG4gICAgICBjb25zdCB3b3JrZXJzID0gd29ya2Vyc0J5VG9rZW4uZ2V0KHdvcmtlci50b2tlbklkKSA/PyBbXTtcbiAgICAgIHdvcmtlcnMucHVzaCh3b3JrZXIpO1xuICAgICAgd29ya2Vyc0J5VG9rZW4uc2V0KHdvcmtlci50b2tlbklkLCB3b3JrZXJzKTtcbiAgICB9XG5cbiAgICBjb25zdCBzZWxlY3RlZFRva2VuSWQgPSB0aGlzLndlaWdodGVkU2VsZWN0b3Iuc2VsZWN0KG5ldyBTZXQod29ya2Vyc0J5VG9rZW4ua2V5cygpKSk7XG4gICAgaWYgKHNlbGVjdGVkVG9rZW5JZCA9PT0gbnVsbCkgcmV0dXJuIG51bGw7XG4gICAgY29uc3Qgd29ya2VycyA9IHdvcmtlcnNCeVRva2VuLmdldChzZWxlY3RlZFRva2VuSWQpITtcbiAgICBjb25zdCBjdXJzb3IgPSB0aGlzLndvcmtlckN1cnNvckJ5VG9rZW4uZ2V0KHNlbGVjdGVkVG9rZW5JZCkgPz8gMDtcbiAgICBmb3IgKGxldCBvZmZzZXQgPSAwOyBvZmZzZXQgPCB3b3JrZXJzLmxlbmd0aDsgb2Zmc2V0KyspIHtcbiAgICAgIGNvbnN0IGluZGV4ID0gKGN1cnNvciArIG9mZnNldCkgJSB3b3JrZXJzLmxlbmd0aDtcbiAgICAgIGNvbnN0IHdvcmtlciA9IHdvcmtlcnNbaW5kZXhdITtcbiAgICAgIGlmICh3b3JrZXIudHJ5QWNxdWlyZVR1cm4oKSkge1xuICAgICAgICB0aGlzLndvcmtlckN1cnNvckJ5VG9rZW4uc2V0KHNlbGVjdGVkVG9rZW5JZCwgKGluZGV4ICsgMSkgJSB3b3JrZXJzLmxlbmd0aCk7XG4gICAgICAgIHJldHVybiB3b3JrZXI7XG4gICAgICB9XG4gICAgfVxuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgIGB3ZWlnaHRlZCB0b2tlbiAke3NlbGVjdGVkVG9rZW5JZH0gbG9zdCBpZGxlIGNhcGFjaXR5IGR1cmluZyBzeW5jaHJvbm91cyBhY3F1aXJlYCxcbiAgICApO1xuICB9XG5cbiAgZ2V0QWxsUmVhZHlBY3RpdmVXb3JrZXJzKCk6IENvZGV4QXBwU2VydmVyV29ya2VyW10ge1xuICAgIHJldHVybiBbLi4udGhpcy53b3JrZXJQb29sLnZhbHVlcygpXS5mbGF0KCkuZmlsdGVyKCh3KSA9PiB3LmlzUmVhZHkgJiYgdy5hY3RpdmUpO1xuICB9XG5cbiAgLy8g4pSA4pSAIFF1ZXVlIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIGFzeW5jIGVucXVldWU8VD4oXG4gICAgZXhlY3V0ZTogKHdvcmtlcjogQ29kZXhBcHBTZXJ2ZXJXb3JrZXIpID0+IFByb21pc2U8VD4sXG4gICAgZXhjbHVkZWRUb2tlbklkcyA9IG5ldyBTZXQ8bnVtYmVyPigpLFxuICApOiBQcm9taXNlPFQ+IHtcbiAgICBjb25zdCBlbGlnaWJpbGl0eSA9IGF3YWl0IHRoaXMucmVzb2x2ZVRva2VuRWxpZ2liaWxpdHkoZXhjbHVkZWRUb2tlbklkcyk7XG4gICAgaWYgKFxuICAgICAgZWxpZ2liaWxpdHkucmVhZHlBY3RpdmVUb2tlbklkcy5zaXplID09PSAwICYmXG4gICAgICAhdGhpcy5oYXNBY3RpdmVUb2tlbkNhbmRpZGF0ZShleGNsdWRlZFRva2VuSWRzKVxuICAgICkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTk9fT1BFTkFJX1dPUktFUlNcIik7XG4gICAgfVxuICAgIGlmIChlbGlnaWJpbGl0eS5yZWFkeUFjdGl2ZVRva2VuSWRzLnNpemUgPiAwICYmIGVsaWdpYmlsaXR5LmVsaWdpYmxlVG9rZW5JZHMuc2l6ZSA9PT0gMCkge1xuICAgICAgdGhpcy50aHJvd1F1b3RhVGhyZXNob2xkRXhjZWVkZWQoZWxpZ2liaWxpdHkpO1xuICAgIH1cbiAgICBpZiAodGhpcy5xdWV1ZS5sZW5ndGggPj0gTUFYX1FVRVVFX1NJWkUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlNFUlZFUl9CVVNZXCIpO1xuICAgIH1cblxuICAgIHJldHVybiBuZXcgUHJvbWlzZTxUPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBjb25zdCBpdGVtOiBRdWV1ZUl0ZW0gPSB7XG4gICAgICAgIHJlc29sdmU6ICh3b3JrZXIpID0+IHtcbiAgICAgICAgICBjbGVhclRpbWVvdXQoaXRlbS50aW1lcik7XG4gICAgICAgICAgaXRlbS5hYm9ydENsZWFudXA/LigpO1xuICAgICAgICAgIFByb21pc2UucmVzb2x2ZSgpXG4gICAgICAgICAgICAudGhlbigoKSA9PiB0aGlzLmV4ZWN1dGVBbmRSZWxlYXNlKHdvcmtlciwgZXhlY3V0ZSkpXG4gICAgICAgICAgICAudGhlbihyZXNvbHZlLCByZWplY3QpO1xuICAgICAgICB9LFxuICAgICAgICByZWplY3Q6IChlcnIpID0+IHtcbiAgICAgICAgICBjbGVhclRpbWVvdXQoaXRlbS50aW1lcik7XG4gICAgICAgICAgaXRlbS5hYm9ydENsZWFudXA/LigpO1xuICAgICAgICAgIHJlamVjdChlcnIpO1xuICAgICAgICB9LFxuICAgICAgICB0aW1lcjogc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgdGhpcy5yZW1vdmVGcm9tUXVldWUoaXRlbSk7XG4gICAgICAgICAgcmVqZWN0KG5ldyBFcnJvcihcIlNFUlZFUl9CVVNZXCIpKTtcbiAgICAgICAgfSwgUVVFVUVfVElNRU9VVF9NUyksXG4gICAgICAgIGV4Y2x1ZGVkVG9rZW5JZHM6IG5ldyBTZXQoZXhjbHVkZWRUb2tlbklkcyksXG4gICAgICB9O1xuXG4gICAgICB0aGlzLnF1ZXVlLnB1c2goaXRlbSk7XG4gICAgICAvLyBlbGlnaWJpbGl0eSDtmZXsnbjqs7wgcXVldWUg7IK97J6FIOyCrOydtOyXkCB3b3JrZXLqsIAgcmVhZHkvaWRsZeydtCDrkJwg6rK97Jqw7J2YIGxvc3Qgd2FrZS11cOydhFxuICAgICAgLy8g64ur64qU64ukLiBmaXhlZCBtb2Rl7JeQ7ISc64+EIGlkbGUgd29ya2Vy6rCAIOymieyLnCBxdWV1ZeulvCDqsIDsoLjqsIDslbwg7ZWc64ukLlxuICAgICAgdGhpcy5yZXF1ZXN0RHJhaW5RdWV1ZSgpO1xuICAgICAgdGhpcy5yZXF1ZXN0QXV0b3NjYWxlRXZhbHVhdGlvbigpO1xuICAgIH0pO1xuICB9XG5cbiAgcmVtb3ZlRnJvbVF1ZXVlKGl0ZW06IFF1ZXVlSXRlbSk6IHZvaWQge1xuICAgIGNsZWFyVGltZW91dChpdGVtLnRpbWVyKTtcbiAgICBpdGVtLmFib3J0Q2xlYW51cD8uKCk7XG4gICAgY29uc3QgaWR4ID0gdGhpcy5xdWV1ZS5pbmRleE9mKGl0ZW0pO1xuICAgIGlmIChpZHggIT09IC0xKSB0aGlzLnF1ZXVlLnNwbGljZShpZHgsIDEpO1xuICB9XG5cbiAgcmVqZWN0QWxsUXVldWVkKHJlYXNvbjogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3QgZXJyID0gbmV3IEVycm9yKHJlYXNvbik7XG4gICAgdGhpcy5xdWV1ZS5mb3JFYWNoKChpdGVtKSA9PiB7XG4gICAgICBjbGVhclRpbWVvdXQoaXRlbS50aW1lcik7XG4gICAgICBpdGVtLmFib3J0Q2xlYW51cD8uKCk7XG4gICAgICBpdGVtLnJlamVjdChlcnIpO1xuICAgIH0pO1xuICAgIHRoaXMucXVldWUgPSBbXTtcbiAgfVxuXG4gIGFzeW5jIGRyYWluUXVldWUoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKHRoaXMuZHJhaW5pbmcpIHtcbiAgICAgIHRoaXMuZHJhaW5BZ2FpbiA9IHRydWU7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5kcmFpbmluZyA9IHRydWU7XG4gICAgdHJ5IHtcbiAgICAgIGRvIHtcbiAgICAgICAgdGhpcy5kcmFpbkFnYWluID0gZmFsc2U7XG4gICAgICAgIGF3YWl0IHRoaXMuZHJhaW5RdWV1ZU9uY2UoKTtcbiAgICAgIH0gd2hpbGUgKHRoaXMuZHJhaW5BZ2Fpbik7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgbG9nZ2VyLndhcm4oYGRyYWluUXVldWUgZmFpbGVkOiAkeyhlIGFzIEVycm9yKS5tZXNzYWdlfWApO1xuICAgIH0gZmluYWxseSB7XG4gICAgICB0aGlzLmRyYWluaW5nID0gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBkcmFpblF1ZXVlT25jZSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB3aGlsZSAodGhpcy5xdWV1ZS5sZW5ndGggPiAwKSB7XG4gICAgICBjb25zdCBuZXh0ID0gdGhpcy5xdWV1ZVswXSE7XG4gICAgICBsZXQgd29ya2VyOiBDb2RleEFwcFNlcnZlcldvcmtlciB8IG51bGw7XG4gICAgICB0cnkge1xuICAgICAgICB3b3JrZXIgPSBhd2FpdCB0aGlzLmFjcXVpcmVJZGxlV29ya2VyKG5leHQuZXhjbHVkZWRUb2tlbklkcyk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGlmIChlIGluc3RhbmNlb2YgUXVvdGFUaHJlc2hvbGRFeGNlZWRlZEVycm9yKSB7XG4gICAgICAgICAgdGhpcy5xdWV1ZS5zaGlmdCgpO1xuICAgICAgICAgIG5leHQucmVqZWN0KGUpO1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIHRocm93IGU7XG4gICAgICB9XG4gICAgICBpZiAoIXdvcmtlcikgYnJlYWs7XG4gICAgICB0aGlzLnF1ZXVlLnNoaWZ0KCk7XG4gICAgICBuZXh0LnJlc29sdmUod29ya2VyKTtcbiAgICB9XG4gIH1cblxuICAvLyDilIDilIAgRXhlY3V0aW9uIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIGFzeW5jIGV4ZWN1dGVBbmRSZWxlYXNlPFQ+KFxuICAgIHdvcmtlcjogQ29kZXhBcHBTZXJ2ZXJXb3JrZXIsXG4gICAgZXhlY3V0ZTogKHdvcmtlcjogQ29kZXhBcHBTZXJ2ZXJXb3JrZXIpID0+IFByb21pc2U8VD4sXG4gICk6IFByb21pc2U8VD4ge1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gYXdhaXQgZXhlY3V0ZSh3b3JrZXIpO1xuICAgIH0gZmluYWxseSB7XG4gICAgICB3b3JrZXIucmVsZWFzZVR1cm4oKTtcbiAgICAgIHRoaXMucmVxdWVzdERyYWluUXVldWUoKTtcbiAgICB9XG4gIH1cblxuICAvLyByZXVzZVRocmVhZElkIOqwgCDsnojsnLzrqbQg6riw7KG0IHRocmVhZCDsl5AgZGVsdGEocmV1c2VJbnB1dCnrp4wsIOyXhuycvOuptCDsg4ggdGhyZWFkIOyXkCDsoITssrRcbiAgLy8gcHJvbXB0KGNvbGRJbnB1dCkgKyBoaXN0b3J5IGluamVjdC4gcmV1c2Ug6rCAIGRpc3BhdGNoZXIg64uo7JeQ7IScIO2PtOuwseuQmOuptCDtm4TsnpDroZwg65ao7Ja07KeE64ukLlxuICBwcml2YXRlIGJ1aWxkVHVyblJlcXVlc3QocmVxOiBHZW5lcmF0ZVJlcXVlc3QsIHJldXNlVGhyZWFkSWQ/OiBzdHJpbmcpOiBUdXJuUmVxdWVzdCB7XG4gICAgY29uc3QgcmV1c2luZyA9IHJldXNlVGhyZWFkSWQgIT09IHVuZGVmaW5lZDtcbiAgICByZXR1cm4ge1xuICAgICAgaW5wdXQ6IHJldXNpbmcgJiYgcmVxLnJldXNlSW5wdXQgPyByZXEucmV1c2VJbnB1dCA6IHJlcS5jb2xkSW5wdXQsXG4gICAgICBoaXN0b3J5OiByZXVzaW5nID8gdW5kZWZpbmVkIDogcmVxLmNvbGRIaXN0b3J5LFxuICAgICAgZGV2ZWxvcGVySW5zdHJ1Y3Rpb25zOiByZXEuc3lzdGVtUHJvbXB0LFxuICAgICAgb3V0cHV0U2NoZW1hOiByZXEub3V0cHV0U2NoZW1hLFxuICAgICAgZWZmb3J0OiByZXEuZWZmb3J0ID8/IERFRkFVTFRfRUZGT1JULFxuICAgICAgbW9kZWw6IHJlcS5tb2RlbCxcbiAgICAgIHZlcmJvc2l0eTogcmVxLnZlcmJvc2l0eSxcbiAgICAgIHJlYXNvbmluZ1N1bW1hcnk6IHJlcS5yZWFzb25pbmdTdW1tYXJ5LFxuICAgICAgc2VydmljZVRpZXI6IHJlcS5zZXJ2aWNlVGllcixcbiAgICAgIGltYWdlR2VuZXJhdGlvbjogcmVxLmltYWdlR2VuZXJhdGlvbixcbiAgICAgIGltYWdlR2VuZXJhdGlvbk9wdGlvbnM6IHJlcS5pbWFnZUdlbmVyYXRpb25PcHRpb25zLFxuICAgIH07XG4gIH1cblxuICBhc3luYyBleGVjdXRlVHVybihcbiAgICB3b3JrZXI6IENvZGV4QXBwU2VydmVyV29ya2VyLFxuICAgIHJlcTogR2VuZXJhdGVSZXF1ZXN0LFxuICAgIHJldXNlVGhyZWFkSWQ/OiBzdHJpbmcsXG4gICk6IFByb21pc2U8R2VuZXJhdGVSZXN1bHQ+IHtcbiAgICAvLyDsnbTrr7jsp4Ag7JqU7LKtIOyCrOyghCDqsozsnbTtirgoUjUpOiDrsLDsoJXrkJwgd29ya2VyIOydmCBjYXBhYmlsaXR5ICsg7KCB7JqpIOuqqOuNuCDrqYDti7Drqqjri6wuXG4gICAgLy8g67aI7Lap7KGx7J2066m0IHR1cm4g7J2EIOyLpO2Wie2VmOyngCDslYrqs6Ag66qF7Iuc7KCBIOyXkOufrC5cbiAgICBpZiAocmVxLmltYWdlR2VuZXJhdGlvbikge1xuICAgICAgY29uc3QgcmVhc29uID0gYXdhaXQgd29ya2VyLmNoZWNrSW1hZ2VHZW5lcmF0aW9uU3VwcG9ydChyZXEubW9kZWwpO1xuICAgICAgaWYgKHJlYXNvbikgdGhyb3cgbmV3IEltYWdlR2VuZXJhdGlvbkVycm9yKFwiZ2F0ZVwiLCByZWFzb24pO1xuICAgIH1cblxuICAgIGNvbnN0IHR1cm5SZXEgPSB0aGlzLmJ1aWxkVHVyblJlcXVlc3QocmVxLCByZXVzZVRocmVhZElkKTtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB3b3JrZXIuZXhlY3V0ZVR1cm4odHVyblJlcSwgcmV1c2VUaHJlYWRJZCk7XG5cbiAgICAvLyDsnbTrr7jsp4AgMOqwnCDsi6TtjKgg67aE66WYKFI2KTogdG9vbCDrr7jtmLjstpwo7J6s7Iuc64+EIOustOydtSkgdnMg7Iuc64+EIO2bhCDrr7jsmYTshLEo7J6s7Iuc64+EIO2bhOuztCkuXG4gICAgaWYgKHJlcS5pbWFnZUdlbmVyYXRpb24gJiYgKCFyZXN1bHQuaW1hZ2VzIHx8IHJlc3VsdC5pbWFnZXMubGVuZ3RoID09PSAwKSkge1xuICAgICAgdGhyb3cgcmVzdWx0LmltYWdlQXR0ZW1wdGVkXG4gICAgICAgID8gbmV3IEltYWdlR2VuZXJhdGlvbkVycm9yKFwiaW5jb21wbGV0ZVwiLCBcImltYWdlIHRvb2wgcmFuIGJ1dCBwcm9kdWNlZCBubyBjb21wbGV0ZWQgaW1hZ2VcIilcbiAgICAgICAgOiBuZXcgSW1hZ2VHZW5lcmF0aW9uRXJyb3IoXCJub3RfY2FsbGVkXCIsIFwibW9kZWwgZGlkIG5vdCBjYWxsIHRoZSBpbWFnZV9nZW5lcmF0aW9uIHRvb2xcIik7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIHRleHQ6IHJlc3VsdC50ZXh0LFxuICAgICAgdG9rZW5OYW1lOiB3b3JrZXIudG9rZW5OYW1lLFxuICAgICAgdXNhZ2U6IHJlc3VsdC51c2FnZSxcbiAgICAgIGR1cmF0aW9uTXM6IHJlc3VsdC5kdXJhdGlvbk1zLFxuICAgICAgdHRmdE1zOiByZXN1bHQudHRmdE1zLFxuICAgICAgbW9kZWw6IHJlc3VsdC5tb2RlbCxcbiAgICAgIHRocmVhZENvb3JkOiB7XG4gICAgICAgIHdvcmtlcklkOiBtYWtlT3BlbkFJV29ya2VySWQod29ya2VyLnRva2VuSWQsIHdvcmtlci53b3JrZXJJbmRleCksXG4gICAgICAgIHRocmVhZElkOiByZXN1bHQudGhyZWFkSWQsXG4gICAgICAgIGVwb2NoOiB3b3JrZXIuZXBvY2gsXG4gICAgICB9LFxuICAgICAgaW1hZ2VzOiByZXN1bHQuaW1hZ2VzLFxuICAgIH07XG4gIH1cblxuICBhc3luYyBleGVjdXRlU3RyZWFtVHVybihcbiAgICB3b3JrZXI6IENvZGV4QXBwU2VydmVyV29ya2VyLFxuICAgIHJlcTogR2VuZXJhdGVSZXF1ZXN0LFxuICAgIGNiOiBHZW5lcmF0ZVN0cmVhbUNhbGxiYWNrcyxcbiAgICByZXVzZVRocmVhZElkPzogc3RyaW5nLFxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCB0dXJuUmVxID0gdGhpcy5idWlsZFR1cm5SZXF1ZXN0KHJlcSwgcmV1c2VUaHJlYWRJZCk7XG4gICAgLy8gd29ya2VyIOydmCBUdXJuUmVzdWx0IOyXkCB0b2tlbk5hbWUvdGhyZWFkQ29vcmQg66W8IOu2meyXrCDsg4HsnIQoR2VuZXJhdGVSZXN1bHQp66GcIOyYrOumsOuLpC5cbiAgICAvLyB0aHJlYWRJZCDripQg7IOIIHRocmVhZCDrqbQgb25UaHJlYWRJZCDroZwg7ZmV7KCV65CY66+A66GcIOuvuOumrCDrs7TqtIDtlbQg65GQ6rOgIG9uQ29tcGxldGUg65WMIOydveuKlOuLpC5cbiAgICBsZXQgcmVzb2x2ZWRUaHJlYWRJZCA9IHJldXNlVGhyZWFkSWQgPz8gXCJcIjtcbiAgICBjb25zdCB3cmFwcGVkQ2I6IFN0cmVhbUNhbGxiYWNrcyA9IHtcbiAgICAgIC4uLmNiLFxuICAgICAgb25UaHJlYWRJZDogKHRocmVhZElkKSA9PiB7XG4gICAgICAgIHJlc29sdmVkVGhyZWFkSWQgPSB0aHJlYWRJZDtcbiAgICAgICAgY2Iub25UaHJlYWRJZD8uKHRocmVhZElkKTtcbiAgICAgIH0sXG4gICAgICBvbkNvbXBsZXRlOiAocmVzdWx0KSA9PiB7XG4gICAgICAgIGNiLm9uQ29tcGxldGUoe1xuICAgICAgICAgIC4uLnJlc3VsdCxcbiAgICAgICAgICB0b2tlbk5hbWU6IHdvcmtlci50b2tlbk5hbWUsXG4gICAgICAgICAgdGhyZWFkQ29vcmQ6IHtcbiAgICAgICAgICAgIHdvcmtlcklkOiBtYWtlT3BlbkFJV29ya2VySWQod29ya2VyLnRva2VuSWQsIHdvcmtlci53b3JrZXJJbmRleCksXG4gICAgICAgICAgICB0aHJlYWRJZDogcmVzb2x2ZWRUaHJlYWRJZCxcbiAgICAgICAgICAgIGVwb2NoOiB3b3JrZXIuZXBvY2gsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICB9LFxuICAgIH07XG4gICAgYXdhaXQgd29ya2VyLmV4ZWN1dGVUdXJuU3RyZWFtKHR1cm5SZXEsIHdyYXBwZWRDYiwgcmV1c2VUaHJlYWRJZCk7XG4gIH1cblxuICAvLyDilIDilIAgU3Bhd24g4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbiAgYXN5bmMgc3Bhd25Xb3JrZXJzKFxuICAgIHRva2VuSWQ6IG51bWJlcixcbiAgICB0b2tlbk5hbWU6IHN0cmluZyxcbiAgICBjcmVkZW50aWFsczogT3BlbkFJQ3JlZGVudGlhbHMsXG4gICAgcXVvdGFUaHJlc2hvbGQ/OiBudW1iZXIgfCBudWxsLFxuICAgIHdlaWdodCA9IDEsXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICh0aGlzLnN0YXJ0aW5nVG9rZW5JZHMuaGFzKHRva2VuSWQpKSByZXR1cm47XG4gICAgdGhpcy5zdGFydGluZ1Rva2VuSWRzLmFkZCh0b2tlbklkKTtcbiAgICB0aGlzLnNldFRva2VuTWV0YWRhdGEodG9rZW5JZCwgdG9rZW5OYW1lLCBjcmVkZW50aWFscywgcXVvdGFUaHJlc2hvbGQsIHdlaWdodCk7XG4gICAgY29uc3QgZXhwZWN0ZWRNZXRhZGF0YSA9IHRoaXMudG9rZW5NZXRhZGF0YS5nZXQodG9rZW5JZCk7XG4gICAgY29uc3Qgd29ya2VyczogQ29kZXhBcHBTZXJ2ZXJXb3JrZXJbXSA9IFtdO1xuICAgIHRyeSB7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMucG9vbENvbmZpZy5taW5Xb3JrZXJzUGVyVG9rZW47IGkrKykge1xuICAgICAgICBpZiAoaSA+IDApIGF3YWl0IHNsZWVwKFNQQVdOX0lOVEVSVkFMX01TKTtcbiAgICAgICAgY29uc3Qgd29ya2VyID0gYXdhaXQgdGhpcy5zcGF3blNpbmdsZVdvcmtlcih0b2tlbklkLCB0b2tlbk5hbWUsIGNyZWRlbnRpYWxzLCBpKTtcbiAgICAgICAgaWYgKHdvcmtlcikgd29ya2Vycy5wdXNoKHdvcmtlcik7XG4gICAgICB9XG5cbiAgICAgIGlmIChcbiAgICAgICAgIXRoaXMuc3RvcHBlZCAmJlxuICAgICAgICBleHBlY3RlZE1ldGFkYXRhPy5hY3RpdmUgJiZcbiAgICAgICAgdGhpcy50b2tlbk1ldGFkYXRhLmdldCh0b2tlbklkKSA9PT0gZXhwZWN0ZWRNZXRhZGF0YSAmJlxuICAgICAgICAhdGhpcy53b3JrZXJQb29sLmhhcyh0b2tlbklkKVxuICAgICAgKSB7XG4gICAgICAgIGlmICh3b3JrZXJzLmxlbmd0aCA+IDApIHRoaXMud29ya2VyUG9vbC5zZXQodG9rZW5JZCwgd29ya2Vycyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBhd2FpdCBQcm9taXNlLmFsbFNldHRsZWQod29ya2Vycy5tYXAoKHdvcmtlcikgPT4gd29ya2VyLmtpbGwoKSkpO1xuICAgICAgfVxuICAgIH0gZmluYWxseSB7XG4gICAgICB0aGlzLnN0YXJ0aW5nVG9rZW5JZHMuZGVsZXRlKHRva2VuSWQpO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIHNwYXduU2luZ2xlV29ya2VyKFxuICAgIHRva2VuSWQ6IG51bWJlcixcbiAgICB0b2tlbk5hbWU6IHN0cmluZyxcbiAgICBjcmVkZW50aWFsczogT3BlbkFJQ3JlZGVudGlhbHMsXG4gICAgd29ya2VySW5kZXg6IG51bWJlcixcbiAgKTogUHJvbWlzZTxDb2RleEFwcFNlcnZlcldvcmtlciB8IG51bGw+IHtcbiAgICBjb25zdCB3b3JrZXIgPSBuZXcgQ29kZXhBcHBTZXJ2ZXJXb3JrZXIoe1xuICAgICAgdG9rZW5JZCxcbiAgICAgIHRva2VuTmFtZSxcbiAgICAgIGFjY2Vzc1Rva2VuOiBjcmVkZW50aWFscy5hY2Nlc3NUb2tlbixcbiAgICAgIGFjY291bnRJZDogY3JlZGVudGlhbHMuYWNjb3VudElkLFxuICAgICAgcGxhblR5cGU6IGNyZWRlbnRpYWxzLnBsYW5UeXBlLFxuICAgICAgd29ya2VySW5kZXgsXG4gICAgfSk7XG5cbiAgICB3b3JrZXIub25SZWFkeSA9ICgpID0+IHRoaXMucmVxdWVzdERyYWluUXVldWUoKTtcbiAgICB3b3JrZXIub25UZXJtaW5hbEZhaWx1cmUgPSAoKSA9PiB7XG4gICAgICB2b2lkIHRoaXMuaGFuZGxlV29ya2VyVGVybWluYWxGYWlsdXJlKHdvcmtlcikuY2F0Y2goKGUpID0+XG4gICAgICAgIGxvZ2dlci53YXJuKFxuICAgICAgICAgIGB0ZXJtaW5hbCB3b3JrZXIgY2xlYW51cCBmYWlsZWQ6ICR7dG9rZW5OYW1lfVske3dvcmtlckluZGV4fV06ICR7KGUgYXMgRXJyb3IpLm1lc3NhZ2V9YCxcbiAgICAgICAgKSxcbiAgICAgICk7XG4gICAgfTtcblxuICAgIHdvcmtlci5zZXRTZXJ2ZXJSZXF1ZXN0SGFuZGxlcihhc3luYyAobWV0aG9kKSA9PiB7XG4gICAgICBpZiAobWV0aG9kID09PSBcImFjY291bnQvY2hhdGdwdEF1dGhUb2tlbnMvcmVmcmVzaFwiKSB7XG4gICAgICAgIHJldHVybiBoYW5kbGVDaGF0Z3B0QXV0aFRva2Vuc1JlZnJlc2godG9rZW5JZCk7XG4gICAgICB9XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYHVuaGFuZGxlZCBzZXJ2ZXItcmVxdWVzdDogJHttZXRob2R9YCk7XG4gICAgfSk7XG5cbiAgICB0cnkge1xuICAgICAgYXdhaXQgd29ya2VyLmluaXRpYWxpemUoKTtcbiAgICAgIGxvZ2dlci5pbmZvKGB3b3JrZXIgc3Bhd25lZDogJHt0b2tlbk5hbWV9WyR7d29ya2VySW5kZXh9XWApO1xuICAgICAgcmV0dXJuIHdvcmtlcjtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBsb2dnZXIud2Fybihgd29ya2VyIHNwYXduIGZhaWxlZDogJHt0b2tlbk5hbWV9WyR7d29ya2VySW5kZXh9XTogJHsoZSBhcyBFcnJvcikubWVzc2FnZX1gKTtcbiAgICAgIGF3YWl0IHdvcmtlci5raWxsKCkuY2F0Y2goKCkgPT4ge30pO1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgZXZhbHVhdGVBdXRvc2NhbGluZygpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAodGhpcy5zdG9wcGVkKSByZXR1cm47XG4gICAgdGhpcy5zd2VlcElkbGVXb3JrZXJUaHJlYWRzKCk7XG4gICAgY29uc3QgbWluaW11bURlZmljaXRUb2tlbklkcyA9IGF3YWl0IHRoaXMuZW5zdXJlTWluaW11bVdvcmtlcnNPbmVTdGVwKCk7XG4gICAgaWYgKCF0aGlzLnBvb2xDb25maWcuYXV0b3NjYWxlIHx8IHRoaXMuc3RvcHBlZCkgcmV0dXJuO1xuICAgIGlmICh0aGlzLnF1ZXVlLmxlbmd0aCA+IDApIHtcbiAgICAgIC8vIGJhc2VsaW5lIOuzteq1rOulvCDsi5zrj4TtlZwgdG9rZW7rp4wg6rCZ7J2AIGV2YWx1YXRpb27snZggZGVtYW5kIGV4cGFuc2lvbuyXkOyEnCDsoJzsmbjtlZzri6QuXG4gICAgICAvLyDri6Trpbgg7KCV7IOBIHRva2Vu7J2YIO2Zleyepeq5jOyngCDrp4nsp4DripQg7JWK64qU64ukLlxuICAgICAgYXdhaXQgdGhpcy5zY2FsZVVwT25lU3RlcChtaW5pbXVtRGVmaWNpdFRva2VuSWRzKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKERhdGUubm93KCkgLSB0aGlzLmxhc3RSZXF1ZXN0QXQgPj0gdGhpcy5wb29sQ29uZmlnLnNjYWxlRG93bklkbGVNcykge1xuICAgICAgYXdhaXQgdGhpcy5zY2FsZURvd25PbmVTdGVwKCk7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgc2NhbGVVcE9uZVN0ZXAoZXhjbHVkZWRUb2tlbklkcyA9IG5ldyBTZXQ8bnVtYmVyPigpKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKCF0aGlzLnBvb2xDb25maWcuYXV0b3NjYWxlIHx8IHRoaXMuc3RvcHBlZCkgcmV0dXJuO1xuICAgIGF3YWl0IHRoaXMucnVuU2NhbGluZyhhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBjYW5kaWRhdGVzID0gWy4uLnRoaXMudG9rZW5NZXRhZGF0YS5lbnRyaWVzKCldLmZpbHRlcigoW3Rva2VuSWQsIG1ldGFkYXRhXSkgPT4ge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgIW1ldGFkYXRhLmFjdGl2ZSB8fFxuICAgICAgICAgIHRoaXMuc3RhcnRpbmdUb2tlbklkcy5oYXModG9rZW5JZCkgfHxcbiAgICAgICAgICBleGNsdWRlZFRva2VuSWRzLmhhcyh0b2tlbklkKSB8fFxuICAgICAgICAgIHRoaXMucXVvdGFCbG9ja2VkVG9rZW5JZHMuaGFzKHRva2VuSWQpXG4gICAgICAgICkge1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gKHRoaXMud29ya2VyUG9vbC5nZXQodG9rZW5JZCk/Lmxlbmd0aCA/PyAwKSA8IHRoaXMucG9vbENvbmZpZy5tYXhXb3JrZXJzUGVyVG9rZW47XG4gICAgICB9KTtcbiAgICAgIGlmIChjYW5kaWRhdGVzLmxlbmd0aCA9PT0gMCkgcmV0dXJuO1xuXG4gICAgICBjb25zdCBwcm9qZWN0ZWRXb3JrZXJDb3VudCA9IHRoaXMud29ya2VyQ291bnQgKyBjYW5kaWRhdGVzLmxlbmd0aDtcbiAgICAgIGNvbnN0IHByb2plY3RlZFJzc0dpQiA9IGVzdGltYXRlT3BlbkFJV29ya2VyUnNzR2lCKHByb2plY3RlZFdvcmtlckNvdW50KTtcbiAgICAgIGlmIChwcm9qZWN0ZWRSc3NHaUIgPiB0aGlzLnBvb2xDb25maWcubWF4RXN0aW1hdGVkUnNzR2lCKSB7XG4gICAgICAgIGxvZ2dlci53YXJuKFxuICAgICAgICAgIGBvcGVuYWkgYXV0b3NjYWxlIGJsb2NrZWQ6IGVzdGltYXRlZCBSU1MgJHtwcm9qZWN0ZWRSc3NHaUIudG9GaXhlZCgyKX1HaUIgZXhjZWVkcyAke3RoaXMucG9vbENvbmZpZy5tYXhFc3RpbWF0ZWRSc3NHaUIudG9GaXhlZCgyKX1HaUJgLFxuICAgICAgICApO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGhvc3RBdmFpbGFibGVHaUIgPSB0aGlzLmdldEhvc3RBdmFpbGFibGVHaUIoKTtcbiAgICAgIGlmIChob3N0QXZhaWxhYmxlR2lCIDwgdGhpcy5wb29sQ29uZmlnLm1pbkhvc3RBdmFpbGFibGVHaUIpIHtcbiAgICAgICAgbG9nZ2VyLndhcm4oXG4gICAgICAgICAgYG9wZW5haSBhdXRvc2NhbGUgYmxvY2tlZDogaG9zdCBhdmFpbGFibGUgJHtob3N0QXZhaWxhYmxlR2lCLnRvRml4ZWQoMil9R2lCIGJlbG93ICR7dGhpcy5wb29sQ29uZmlnLm1pbkhvc3RBdmFpbGFibGVHaUIudG9GaXhlZCgyKX1HaUJgLFxuICAgICAgICApO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHNwYXduZWQgPSBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgICAgY2FuZGlkYXRlcy5tYXAoKFt0b2tlbklkLCBtZXRhZGF0YV0pID0+IHRoaXMuc3Bhd25BbmRDb21taXRXb3JrZXIodG9rZW5JZCwgbWV0YWRhdGEsIHRydWUpKSxcbiAgICAgICk7XG5cbiAgICAgIGNvbnN0IGFkZGVkID0gc3Bhd25lZC5maWx0ZXIoKHdvcmtlcikgPT4gd29ya2VyICE9PSBudWxsKS5sZW5ndGg7XG4gICAgICBpZiAoYWRkZWQgPiAwKSB7XG4gICAgICAgIGxvZ2dlci5pbmZvKFxuICAgICAgICAgIGBvcGVuYWkgYXV0b3NjYWxlIHVwOiArJHthZGRlZH0gd29ya2VycyAoJHt0aGlzLndvcmtlckNvdW50fSB0b3RhbCwgcXVldWUgJHt0aGlzLnF1ZXVlLmxlbmd0aH0pYCxcbiAgICAgICAgKTtcbiAgICAgICAgdGhpcy5yZXF1ZXN0RHJhaW5RdWV1ZSgpO1xuICAgICAgICBpZiAodGhpcy5xdWV1ZS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgY29uc3QgdGltZXIgPSBzZXRUaW1lb3V0KFxuICAgICAgICAgICAgKCkgPT4gdGhpcy5yZXF1ZXN0QXV0b3NjYWxlRXZhbHVhdGlvbigpLFxuICAgICAgICAgICAgTWF0aC5taW4odGhpcy5wb29sQ29uZmlnLnNjYWxlSW50ZXJ2YWxNcywgMV8wMDApLFxuICAgICAgICAgICk7XG4gICAgICAgICAgdGltZXIudW5yZWY/LigpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBhc3luYyBlbnN1cmVNaW5pbXVtV29ya2Vyc09uZVN0ZXAoKTogUHJvbWlzZTxTZXQ8bnVtYmVyPj4ge1xuICAgIGNvbnN0IG1pbmltdW1EZWZpY2l0VG9rZW5JZHMgPSBuZXcgU2V0PG51bWJlcj4oKTtcbiAgICBpZiAodGhpcy5zdG9wcGVkKSByZXR1cm4gbWluaW11bURlZmljaXRUb2tlbklkcztcbiAgICBhd2FpdCB0aGlzLnJ1blNjYWxpbmcoYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgY2FuZGlkYXRlcyA9IFsuLi50aGlzLnRva2VuTWV0YWRhdGEuZW50cmllcygpXS5maWx0ZXIoKFt0b2tlbklkLCBtZXRhZGF0YV0pID0+IHtcbiAgICAgICAgaWYgKCFtZXRhZGF0YS5hY3RpdmUgfHwgdGhpcy5zdGFydGluZ1Rva2VuSWRzLmhhcyh0b2tlbklkKSkgcmV0dXJuIGZhbHNlO1xuICAgICAgICByZXR1cm4gKHRoaXMud29ya2VyUG9vbC5nZXQodG9rZW5JZCk/Lmxlbmd0aCA/PyAwKSA8IHRoaXMucG9vbENvbmZpZy5taW5Xb3JrZXJzUGVyVG9rZW47XG4gICAgICB9KTtcbiAgICAgIGlmIChjYW5kaWRhdGVzLmxlbmd0aCA9PT0gMCkgcmV0dXJuO1xuICAgICAgY2FuZGlkYXRlcy5mb3JFYWNoKChbdG9rZW5JZF0pID0+IG1pbmltdW1EZWZpY2l0VG9rZW5JZHMuYWRkKHRva2VuSWQpKTtcblxuICAgICAgY29uc3Qgc3Bhd25lZCA9IGF3YWl0IFByb21pc2UuYWxsKFxuICAgICAgICBjYW5kaWRhdGVzLm1hcCgoW3Rva2VuSWQsIG1ldGFkYXRhXSkgPT5cbiAgICAgICAgICB0aGlzLnNwYXduQW5kQ29tbWl0V29ya2VyKHRva2VuSWQsIG1ldGFkYXRhLCBmYWxzZSksXG4gICAgICAgICksXG4gICAgICApO1xuICAgICAgY29uc3QgYWRkZWQgPSBzcGF3bmVkLmZpbHRlcigod29ya2VyKSA9PiB3b3JrZXIgIT09IG51bGwpLmxlbmd0aDtcbiAgICAgIGlmIChhZGRlZCA+IDApIHtcbiAgICAgICAgbG9nZ2VyLmluZm8oYG9wZW5haSB3b3JrZXIgcG9vbCByZXBhaXJlZDogKyR7YWRkZWR9IHdvcmtlcnMgKCR7dGhpcy53b3JrZXJDb3VudH0gdG90YWwpYCk7XG4gICAgICAgIHRoaXMucmVxdWVzdERyYWluUXVldWUoKTtcbiAgICAgICAgaWYgKHRoaXMucXVldWUubGVuZ3RoID4gMCkge1xuICAgICAgICAgIGNvbnN0IHRpbWVyID0gc2V0VGltZW91dChcbiAgICAgICAgICAgICgpID0+IHRoaXMucmVxdWVzdEF1dG9zY2FsZUV2YWx1YXRpb24oKSxcbiAgICAgICAgICAgIE1hdGgubWluKHRoaXMucG9vbENvbmZpZy5zY2FsZUludGVydmFsTXMsIDFfMDAwKSxcbiAgICAgICAgICApO1xuICAgICAgICAgIHRpbWVyLnVucmVmPy4oKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiBtaW5pbXVtRGVmaWNpdFRva2VuSWRzO1xuICB9XG5cbiAgYXN5bmMgc2NhbGVEb3duT25lU3RlcCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAoIXRoaXMucG9vbENvbmZpZy5hdXRvc2NhbGUgfHwgdGhpcy5zdG9wcGVkKSByZXR1cm47XG4gICAgYXdhaXQgdGhpcy5ydW5TY2FsaW5nKGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHJlbW92ZWQ6IENvZGV4QXBwU2VydmVyV29ya2VyW10gPSBbXTtcbiAgICAgIGZvciAoY29uc3QgdG9rZW5JZCBvZiB0aGlzLnRva2VuTWV0YWRhdGEua2V5cygpKSB7XG4gICAgICAgIGNvbnN0IHdvcmtlcnMgPSB0aGlzLndvcmtlclBvb2wuZ2V0KHRva2VuSWQpID8/IFtdO1xuICAgICAgICBpZiAod29ya2Vycy5sZW5ndGggPD0gdGhpcy5wb29sQ29uZmlnLm1pbldvcmtlcnNQZXJUb2tlbikgY29udGludWU7XG5cbiAgICAgICAgY29uc3Qgd29ya2VyID0gd29ya2Vyc1xuICAgICAgICAgIC50b1NvcnRlZCgoYSwgYikgPT4gYi53b3JrZXJJbmRleCAtIGEud29ya2VySW5kZXgpXG4gICAgICAgICAgLmZpbmQoKGVudHJ5KSA9PiBlbnRyeS5oYXNDYXBhY2l0eSk7XG4gICAgICAgIGlmICghd29ya2VyKSBjb250aW51ZTtcblxuICAgICAgICB0aGlzLndvcmtlclBvb2wuc2V0KFxuICAgICAgICAgIHRva2VuSWQsXG4gICAgICAgICAgd29ya2Vycy5maWx0ZXIoKGVudHJ5KSA9PiBlbnRyeSAhPT0gd29ya2VyKSxcbiAgICAgICAgKTtcbiAgICAgICAgcmVtb3ZlZC5wdXNoKHdvcmtlcik7XG4gICAgICB9XG5cbiAgICAgIGlmIChyZW1vdmVkLmxlbmd0aCA9PT0gMCkgcmV0dXJuO1xuICAgICAgYXdhaXQgUHJvbWlzZS5hbGxTZXR0bGVkKHJlbW92ZWQubWFwKCh3b3JrZXIpID0+IHdvcmtlci5raWxsKCkpKTtcbiAgICAgIGxvZ2dlci5pbmZvKGBvcGVuYWkgYXV0b3NjYWxlIGRvd246IC0ke3JlbW92ZWQubGVuZ3RofSB3b3JrZXJzICgke3RoaXMud29ya2VyQ291bnR9IHRvdGFsKWApO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBuZXh0QXZhaWxhYmxlV29ya2VySW5kZXgod29ya2VyczogQ29kZXhBcHBTZXJ2ZXJXb3JrZXJbXSk6IG51bWJlciB7XG4gICAgY29uc3QgdXNlZCA9IG5ldyBTZXQod29ya2Vycy5tYXAoKHdvcmtlcikgPT4gd29ya2VyLndvcmtlckluZGV4KSk7XG4gICAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IHRoaXMucG9vbENvbmZpZy5tYXhXb3JrZXJzUGVyVG9rZW47IGluZGV4KyspIHtcbiAgICAgIGlmICghdXNlZC5oYXMoaW5kZXgpKSByZXR1cm4gaW5kZXg7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnBvb2xDb25maWcubWF4V29ya2Vyc1BlclRva2VuO1xuICB9XG5cbiAgcHJpdmF0ZSBzd2VlcElkbGVXb3JrZXJUaHJlYWRzKCk6IHZvaWQge1xuICAgIGZvciAoY29uc3Qgd29ya2VyIG9mIFsuLi50aGlzLndvcmtlclBvb2wudmFsdWVzKCldLmZsYXQoKSkge1xuICAgICAgLy8gdHVybiDspJEgdW5zdWJzY3JpYmXtlZjrqbQg7ZW064u5IGNvbm5lY3Rpb27snLzroZwgbm90aWZpY2F0aW9u7J20IOuNlCDsmKTsp4Ag7JWK7JWEXG4gICAgICAvLyDsi6Ttlokg7KSRIOyalOyyreydtCB0aW1lb3V065CgIOyImCDsnojri6QuIHJlYWR5ICsgaWRsZSB3b3JrZXLrp4wgc3dlZXDtlZzri6QuXG4gICAgICBpZiAod29ya2VyLmlzUmVhZHkgJiYgd29ya2VyLmhhc0NhcGFjaXR5KSB3b3JrZXIuc3dlZXBJZGxlVGhyZWFkcygpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgc3Bhd25BbmRDb21taXRXb3JrZXIoXG4gICAgdG9rZW5JZDogbnVtYmVyLFxuICAgIG1ldGFkYXRhOiBUb2tlbk1ldGFkYXRhLFxuICAgIHJlc3BlY3RRdW90YUJsb2NrOiBib29sZWFuLFxuICApOiBQcm9taXNlPENvZGV4QXBwU2VydmVyV29ya2VyIHwgbnVsbD4ge1xuICAgIGNvbnN0IGV4cGVjdGVkV29ya2VycyA9IHRoaXMud29ya2VyUG9vbC5nZXQodG9rZW5JZCk7XG4gICAgY29uc3Qgd29ya2VySW5kZXggPSB0aGlzLm5leHRBdmFpbGFibGVXb3JrZXJJbmRleChleHBlY3RlZFdvcmtlcnMgPz8gW10pO1xuICAgIGlmICh3b3JrZXJJbmRleCA+PSB0aGlzLnBvb2xDb25maWcubWF4V29ya2Vyc1BlclRva2VuKSByZXR1cm4gbnVsbDtcblxuICAgIGNvbnN0IHdvcmtlciA9IGF3YWl0IHRoaXMuc3Bhd25TaW5nbGVXb3JrZXIoXG4gICAgICB0b2tlbklkLFxuICAgICAgbWV0YWRhdGEubmFtZSxcbiAgICAgIG1ldGFkYXRhLmNyZWRlbnRpYWxzLFxuICAgICAgd29ya2VySW5kZXgsXG4gICAgKTtcbiAgICBpZiAoIXdvcmtlcikgcmV0dXJuIG51bGw7XG5cbiAgICBjb25zdCBjdXJyZW50TWV0YWRhdGEgPSB0aGlzLnRva2VuTWV0YWRhdGEuZ2V0KHRva2VuSWQpO1xuICAgIGNvbnN0IGN1cnJlbnRXb3JrZXJzID0gdGhpcy53b3JrZXJQb29sLmdldCh0b2tlbklkKTtcbiAgICBpZiAoXG4gICAgICAhY3VycmVudE1ldGFkYXRhPy5hY3RpdmUgfHxcbiAgICAgIGN1cnJlbnRNZXRhZGF0YSAhPT0gbWV0YWRhdGEgfHxcbiAgICAgIGN1cnJlbnRXb3JrZXJzICE9PSBleHBlY3RlZFdvcmtlcnMgfHxcbiAgICAgIChyZXNwZWN0UXVvdGFCbG9jayAmJiB0aGlzLnF1b3RhQmxvY2tlZFRva2VuSWRzLmhhcyh0b2tlbklkKSkgfHxcbiAgICAgIGN1cnJlbnRXb3JrZXJzPy5zb21lKChlbnRyeSkgPT4gZW50cnkud29ya2VySW5kZXggPT09IHdvcmtlckluZGV4KVxuICAgICkge1xuICAgICAgYXdhaXQgd29ya2VyLmtpbGwoKS5jYXRjaCgoKSA9PiB7fSk7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBjb25zdCBuZXh0V29ya2VycyA9IGN1cnJlbnRXb3JrZXJzID8/IFtdO1xuICAgIG5leHRXb3JrZXJzLnB1c2god29ya2VyKTtcbiAgICBuZXh0V29ya2Vycy5zb3J0KChhLCBiKSA9PiBhLndvcmtlckluZGV4IC0gYi53b3JrZXJJbmRleCk7XG4gICAgaWYgKCFjdXJyZW50V29ya2VycykgdGhpcy53b3JrZXJQb29sLnNldCh0b2tlbklkLCBuZXh0V29ya2Vycyk7XG4gICAgcmV0dXJuIHdvcmtlcjtcbiAgfVxuXG4gIGFzeW5jIGhhbmRsZVdvcmtlclRlcm1pbmFsRmFpbHVyZSh3b3JrZXI6IENvZGV4QXBwU2VydmVyV29ya2VyKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3Qgd29ya2VycyA9IHRoaXMud29ya2VyUG9vbC5nZXQod29ya2VyLnRva2VuSWQpO1xuICAgIGlmICghd29ya2Vycz8uaW5jbHVkZXMod29ya2VyKSkgcmV0dXJuO1xuXG4gICAgYXdhaXQgd29ya2VyLmtpbGwoKS5jYXRjaCgoKSA9PiB7fSk7XG5cbiAgICBjb25zdCBjdXJyZW50V29ya2VycyA9IHRoaXMud29ya2VyUG9vbC5nZXQod29ya2VyLnRva2VuSWQpO1xuICAgIGlmICghY3VycmVudFdvcmtlcnM/LmluY2x1ZGVzKHdvcmtlcikpIHJldHVybjtcbiAgICBjb25zdCByZW1haW5pbmcgPSBjdXJyZW50V29ya2Vycy5maWx0ZXIoKGVudHJ5KSA9PiBlbnRyeSAhPT0gd29ya2VyKTtcbiAgICBpZiAocmVtYWluaW5nLmxlbmd0aCA+IDApIHtcbiAgICAgIHRoaXMud29ya2VyUG9vbC5zZXQod29ya2VyLnRva2VuSWQsIHJlbWFpbmluZyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMud29ya2VyUG9vbC5kZWxldGUod29ya2VyLnRva2VuSWQpO1xuICAgIH1cbiAgICBsb2dnZXIud2FybihcbiAgICAgIGB0ZXJtaW5hbCB3b3JrZXIgcmVtb3ZlZDogJHt3b3JrZXIudG9rZW5OYW1lfVske3dvcmtlci53b3JrZXJJbmRleH1dICgke3JlbWFpbmluZy5sZW5ndGh9IHJlbWFpbmluZylgLFxuICAgICk7XG4gICAgdGhpcy5yZXF1ZXN0QXV0b3NjYWxlRXZhbHVhdGlvbigpO1xuICB9XG5cbiAgcHJpdmF0ZSByZXF1ZXN0QXV0b3NjYWxlRXZhbHVhdGlvbigpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5zdG9wcGVkKSByZXR1cm47XG4gICAgdm9pZCB0aGlzLmV2YWx1YXRlQXV0b3NjYWxpbmcoKS5jYXRjaCgoZSkgPT5cbiAgICAgIGxvZ2dlci53YXJuKGBvcGVuYWkgYXV0b3NjYWxlIGV2YWx1YXRpb24gZmFpbGVkOiAkeyhlIGFzIEVycm9yKS5tZXNzYWdlfWApLFxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHJ1blNjYWxpbmcodGFzazogKCkgPT4gUHJvbWlzZTx2b2lkPik6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICh0aGlzLnNjYWxpbmdQcm9taXNlKSB7XG4gICAgICBhd2FpdCB0aGlzLnNjYWxpbmdQcm9taXNlO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBzY2FsaW5nID0gdGFzaygpLmZpbmFsbHkoKCkgPT4ge1xuICAgICAgaWYgKHRoaXMuc2NhbGluZ1Byb21pc2UgPT09IHNjYWxpbmcpIHRoaXMuc2NhbGluZ1Byb21pc2UgPSBudWxsO1xuICAgIH0pO1xuICAgIHRoaXMuc2NhbGluZ1Byb21pc2UgPSBzY2FsaW5nO1xuICAgIGF3YWl0IHNjYWxpbmc7XG4gIH1cblxuICAvLyDilIDilIAgUmF0ZSBsaW1pdHMg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbiAgcmF0ZUxpbWl0c0NhY2hlID0gbmV3IE1hcDxudW1iZXIsIFJhdGVMaW1pdHNDYWNoZUVudHJ5PigpO1xuICBzdGF0aWMgcmVhZG9ubHkgUkFURV9MSU1JVFNfQ0FDSEVfVFRMID0gNjBfMDAwO1xuXG4gIGFzeW5jIGdldFJhdGVMaW1pdHNCeVRva2VuSWQodG9rZW5JZDogbnVtYmVyKTogUHJvbWlzZTxPcGVuQUlSYXRlTGltaXRzV2l0aE1ldGE+IHtcbiAgICBjb25zdCBnZW5lcmF0aW9uID0gdGhpcy5yYXRlTGltaXRzR2VuZXJhdGlvbkJ5VG9rZW4uZ2V0KHRva2VuSWQpID8/IDA7XG4gICAgY29uc3QgY2FjaGVkID0gdGhpcy5yYXRlTGltaXRzQ2FjaGUuZ2V0KHRva2VuSWQpO1xuICAgIGlmIChcbiAgICAgIGNhY2hlZCAmJlxuICAgICAgY2FjaGVkLmdlbmVyYXRpb24gPT09IGdlbmVyYXRpb24gJiZcbiAgICAgIERhdGUubm93KCkgLSBjYWNoZWQuY2FjaGVkQXQgPCBPcGVuQUlEaXNwYXRjaGVyLlJBVEVfTElNSVRTX0NBQ0hFX1RUTFxuICAgICkge1xuICAgICAgcmV0dXJuIHsgZGF0YTogY2FjaGVkLmRhdGEsIGNhY2hlZEF0OiBjYWNoZWQuY2FjaGVkQXQgfTtcbiAgICB9XG5cbiAgICBjb25zdCB3b3JrZXIgPSAodGhpcy53b3JrZXJQb29sLmdldCh0b2tlbklkKSA/PyBbXSkuZmluZCgodykgPT4gdy5pc1JlYWR5KTtcbiAgICBpZiAoIXdvcmtlcikgdGhyb3cgbmV3IEVycm9yKFwibm8gcmVhZHkgb3BlbmFpIHdvcmtlcnNcIik7XG4gICAgY29uc3QgZGF0YSA9IChhd2FpdCB3b3JrZXIuZ2V0UmF0ZUxpbWl0cygpKSBhcyBHZXRBY2NvdW50UmF0ZUxpbWl0c1Jlc3BvbnNlO1xuICAgIGNvbnN0IGVudHJ5OiBSYXRlTGltaXRzQ2FjaGVFbnRyeSA9IHsgZGF0YSwgY2FjaGVkQXQ6IERhdGUubm93KCksIGdlbmVyYXRpb24gfTtcbiAgICBpZiAoKHRoaXMucmF0ZUxpbWl0c0dlbmVyYXRpb25CeVRva2VuLmdldCh0b2tlbklkKSA/PyAwKSA9PT0gZ2VuZXJhdGlvbikge1xuICAgICAgdGhpcy5yYXRlTGltaXRzQ2FjaGUuc2V0KHRva2VuSWQsIGVudHJ5KTtcbiAgICB9XG4gICAgcmV0dXJuIHsgZGF0YTogZW50cnkuZGF0YSwgY2FjaGVkQXQ6IGVudHJ5LmNhY2hlZEF0IH07XG4gIH1cblxuICBwcml2YXRlIHJlcXVlc3REcmFpblF1ZXVlKCk6IHZvaWQge1xuICAgIHZvaWQgdGhpcy5kcmFpblF1ZXVlKCkuY2F0Y2goKGUpID0+IGxvZ2dlci53YXJuKGBkcmFpblF1ZXVlIGZhaWxlZDogJHsoZSBhcyBFcnJvcikubWVzc2FnZX1gKSk7XG4gIH1cblxuICBwcml2YXRlIGludmFsaWRhdGVSYXRlTGltaXRzQ2FjaGUodG9rZW5JZDogbnVtYmVyKTogdm9pZCB7XG4gICAgdGhpcy5yYXRlTGltaXRzQ2FjaGUuZGVsZXRlKHRva2VuSWQpO1xuICAgIHRoaXMucmF0ZUxpbWl0c0dlbmVyYXRpb25CeVRva2VuLnNldChcbiAgICAgIHRva2VuSWQsXG4gICAgICAodGhpcy5yYXRlTGltaXRzR2VuZXJhdGlvbkJ5VG9rZW4uZ2V0KHRva2VuSWQpID8/IDApICsgMSxcbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSBzZXRUb2tlbk1ldGFkYXRhKFxuICAgIGlkOiBudW1iZXIsXG4gICAgbmFtZTogc3RyaW5nLFxuICAgIGNyZWRlbnRpYWxzOiBPcGVuQUlDcmVkZW50aWFscyxcbiAgICBxdW90YVRocmVzaG9sZDogbnVtYmVyIHwgbnVsbCB8IHVuZGVmaW5lZCxcbiAgICB3ZWlnaHQ6IG51bWJlcixcbiAgKTogdm9pZCB7XG4gICAgdGhpcy50b2tlbk1ldGFkYXRhLnNldChpZCwge1xuICAgICAgbmFtZSxcbiAgICAgIGNyZWRlbnRpYWxzLFxuICAgICAgcXVvdGFUaHJlc2hvbGQsXG4gICAgICB3ZWlnaHQsXG4gICAgICBhY3RpdmU6IHRoaXMudG9rZW5NZXRhZGF0YS5nZXQoaWQpPy5hY3RpdmUgPz8gdHJ1ZSxcbiAgICB9KTtcbiAgICB0aGlzLndlaWdodGVkU2VsZWN0b3Iuc2V0VG9rZW4oaWQsIHdlaWdodCk7XG4gIH1cblxuICBwcml2YXRlIGhhc0FjdGl2ZVRva2VuQ2FuZGlkYXRlKGV4Y2x1ZGVkVG9rZW5JZHM6IFNldDxudW1iZXI+KTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIFsuLi50aGlzLnRva2VuTWV0YWRhdGEuZW50cmllcygpXS5zb21lKFxuICAgICAgKFt0b2tlbklkLCBtZXRhZGF0YV0pID0+IG1ldGFkYXRhLmFjdGl2ZSAmJiAhZXhjbHVkZWRUb2tlbklkcy5oYXModG9rZW5JZCksXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0UXVvdGFUaHJlc2hvbGQodG9rZW5JZDogbnVtYmVyKTogbnVtYmVyIHwgbnVsbCB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMudG9rZW5NZXRhZGF0YS5nZXQodG9rZW5JZCk/LnF1b3RhVGhyZXNob2xkO1xuICB9XG5cbiAgcHJpdmF0ZSBoYXNRdW90YVRocmVzaG9sZCh0b2tlbklkOiBudW1iZXIpOiBib29sZWFuIHtcbiAgICBjb25zdCB0aHJlc2hvbGQgPSB0aGlzLmdldFF1b3RhVGhyZXNob2xkKHRva2VuSWQpO1xuICAgIHJldHVybiB0aHJlc2hvbGQgIT09IHVuZGVmaW5lZCAmJiB0aHJlc2hvbGQgIT09IG51bGw7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHJlc29sdmVUb2tlbkVsaWdpYmlsaXR5KGV4Y2x1ZGVkVG9rZW5JZHM6IFNldDxudW1iZXI+KTogUHJvbWlzZTxUb2tlbkVsaWdpYmlsaXR5PiB7XG4gICAgY29uc3Qgd29ya2VycyA9IHRoaXMuZ2V0QWxsUmVhZHlBY3RpdmVXb3JrZXJzKCk7XG4gICAgY29uc3QgYnlUb2tlbiA9IG5ldyBNYXA8bnVtYmVyLCBzdHJpbmc+KCk7XG4gICAgZm9yIChjb25zdCB3b3JrZXIgb2Ygd29ya2Vycykge1xuICAgICAgaWYgKCFieVRva2VuLmhhcyh3b3JrZXIudG9rZW5JZCkpIGJ5VG9rZW4uc2V0KHdvcmtlci50b2tlbklkLCB3b3JrZXIudG9rZW5OYW1lKTtcbiAgICB9XG5cbiAgICBjb25zdCByZWFkeUFjdGl2ZVRva2VuSWRzID0gbmV3IFNldChieVRva2VuLmtleXMoKSk7XG4gICAgY29uc3QgZWxpZ2libGVUb2tlbklkcyA9IG5ldyBTZXQ8bnVtYmVyPigpO1xuICAgIGNvbnN0IG92ZXJUaHJlc2hvbGRUb2tlbnM6IEFycmF5PHsgdG9rZW5OYW1lOiBzdHJpbmc7IHRocmVzaG9sZDogbnVtYmVyIH0+ID0gW107XG4gICAgbGV0IHRocmVzaG9sZGVkVG9rZW5Db3VudCA9IDA7XG5cbiAgICBjb25zdCBlbnRyaWVzID0gQXJyYXkuZnJvbShieVRva2VuLmVudHJpZXMoKSk7XG4gICAgY29uc3QgY2hlY2tzID0gYXdhaXQgUHJvbWlzZS5hbGxTZXR0bGVkKFxuICAgICAgZW50cmllcy5tYXAoYXN5bmMgKFt0b2tlbklkLCB0b2tlbk5hbWVdKSA9PiB7XG4gICAgICAgIGlmIChleGNsdWRlZFRva2VuSWRzLmhhcyh0b2tlbklkKSkge1xuICAgICAgICAgIHRocmVzaG9sZGVkVG9rZW5Db3VudCsrO1xuICAgICAgICAgIHJldHVybiB7IHRva2VuSWQsIHRva2VuTmFtZSwgZWxpZ2libGU6IGZhbHNlIH07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCF0aGlzLmhhc1F1b3RhVGhyZXNob2xkKHRva2VuSWQpKSB7XG4gICAgICAgICAgcmV0dXJuIHsgdG9rZW5JZCwgdG9rZW5OYW1lLCBlbGlnaWJsZTogdHJ1ZSB9O1xuICAgICAgICB9XG4gICAgICAgIHRocmVzaG9sZGVkVG9rZW5Db3VudCsrO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHRva2VuSWQsXG4gICAgICAgICAgdG9rZW5OYW1lLFxuICAgICAgICAgIGVsaWdpYmxlOiBhd2FpdCB0aGlzLmlzVG9rZW5RdW90YUVsaWdpYmxlKHRva2VuSWQsIHRva2VuTmFtZSksXG4gICAgICAgIH07XG4gICAgICB9KSxcbiAgICApO1xuXG4gICAgY2hlY2tzLmZvckVhY2goKGNoZWNrLCBpbmRleCkgPT4ge1xuICAgICAgaWYgKGNoZWNrLnN0YXR1cyA9PT0gXCJmdWxmaWxsZWRcIikge1xuICAgICAgICBpZiAoY2hlY2sudmFsdWUuZWxpZ2libGUpIHtcbiAgICAgICAgICBlbGlnaWJsZVRva2VuSWRzLmFkZChjaGVjay52YWx1ZS50b2tlbklkKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb25zdCB0aHJlc2hvbGQgPSB0aGlzLmdldFF1b3RhVGhyZXNob2xkKGNoZWNrLnZhbHVlLnRva2VuSWQpO1xuICAgICAgICAgIGlmICh0aHJlc2hvbGQgIT09IHVuZGVmaW5lZCAmJiB0aHJlc2hvbGQgIT09IG51bGwpIHtcbiAgICAgICAgICAgIG92ZXJUaHJlc2hvbGRUb2tlbnMucHVzaCh7IHRva2VuTmFtZTogY2hlY2sudmFsdWUudG9rZW5OYW1lLCB0aHJlc2hvbGQgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgY29uc3QgZW50cnkgPSBlbnRyaWVzW2luZGV4XTtcbiAgICAgIGlmIChlbnRyeSkge1xuICAgICAgICBjb25zdCBbdG9rZW5JZCwgdG9rZW5OYW1lXSA9IGVudHJ5O1xuICAgICAgICB0aGlzLmxvZ1F1b3RhTG9va3VwRmFpbE9wZW4odG9rZW5JZCwgdG9rZW5OYW1lLCBTdHJpbmcoY2hlY2sucmVhc29uKSk7XG4gICAgICAgIGVsaWdpYmxlVG9rZW5JZHMuYWRkKHRva2VuSWQpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIHsgcmVhZHlBY3RpdmVUb2tlbklkcywgZWxpZ2libGVUb2tlbklkcywgb3ZlclRocmVzaG9sZFRva2VucywgdGhyZXNob2xkZWRUb2tlbkNvdW50IH07XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGlzVG9rZW5RdW90YUVsaWdpYmxlKFxuICAgIHRva2VuSWQ6IG51bWJlcixcbiAgICB0b2tlbk5hbWU6IHN0cmluZyxcbiAgICBleGNsdWRlZFRva2VuSWRzPzogU2V0PG51bWJlcj4sXG4gICk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIGZvciAoOzspIHtcbiAgICAgIGNvbnN0IHRva2VuTWV0YWRhdGEgPSB0aGlzLnRva2VuTWV0YWRhdGEuZ2V0KHRva2VuSWQpO1xuICAgICAgY29uc3QgdGhyZXNob2xkID0gdG9rZW5NZXRhZGF0YT8ucXVvdGFUaHJlc2hvbGQ7XG4gICAgICBpZiAoIXRva2VuTWV0YWRhdGE/LmFjdGl2ZSB8fCB0aHJlc2hvbGQgPT09IHVuZGVmaW5lZCB8fCB0aHJlc2hvbGQgPT09IG51bGwpIHtcbiAgICAgICAgdGhpcy5xdW90YUJsb2NrZWRUb2tlbklkcy5kZWxldGUodG9rZW5JZCk7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuXG4gICAgICBsZXQgcmVzdWx0OiBPcGVuQUlRdW90YVVzYWdlUmVzdWx0O1xuICAgICAgdHJ5IHtcbiAgICAgICAgcmVzdWx0ID0gYXdhaXQgcmVhZE9wZW5BSVF1b3RhVXNhZ2UoKCkgPT4gdGhpcy5nZXRSYXRlTGltaXRzQnlUb2tlbklkKHRva2VuSWQpKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgaWYgKHRoaXMudG9rZW5NZXRhZGF0YS5nZXQodG9rZW5JZCkgIT09IHRva2VuTWV0YWRhdGEpIGNvbnRpbnVlO1xuICAgICAgICB0aGlzLnF1b3RhQmxvY2tlZFRva2VuSWRzLmRlbGV0ZSh0b2tlbklkKTtcbiAgICAgICAgdGhpcy5sb2dRdW90YUxvb2t1cEZhaWxPcGVuKHRva2VuSWQsIHRva2VuTWV0YWRhdGEubmFtZSA/PyB0b2tlbk5hbWUsIChlIGFzIEVycm9yKS5tZXNzYWdlKTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLnRva2VuTWV0YWRhdGEuZ2V0KHRva2VuSWQpICE9PSB0b2tlbk1ldGFkYXRhKSBjb250aW51ZTtcblxuICAgICAgaWYgKHJlc3VsdC5raW5kID09PSBcImxvb2t1cF9mYWlsZWRcIikge1xuICAgICAgICB0aGlzLnF1b3RhQmxvY2tlZFRva2VuSWRzLmRlbGV0ZSh0b2tlbklkKTtcbiAgICAgICAgdGhpcy5sb2dRdW90YUxvb2t1cEZhaWxPcGVuKHRva2VuSWQsIHRva2VuTWV0YWRhdGEubmFtZSA/PyB0b2tlbk5hbWUsIHJlc3VsdC5yZWFzb24pO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKHJlc3VsdC51dGlsaXphdGlvblBjdCA+PSB0aHJlc2hvbGQpIHtcbiAgICAgICAgY29uc3QgdHJhbnNpdGlvbmVkID0gIXRoaXMucXVvdGFCbG9ja2VkVG9rZW5JZHMuaGFzKHRva2VuSWQpO1xuICAgICAgICB0aGlzLnF1b3RhQmxvY2tlZFRva2VuSWRzLmFkZCh0b2tlbklkKTtcbiAgICAgICAgaWYgKHRyYW5zaXRpb25lZCkge1xuICAgICAgICAgIHRoaXMubG9nUXVvdGFPdmVyVGhyZXNob2xkKHRva2VuSWQsIHRva2VuTWV0YWRhdGEubmFtZSA/PyB0b2tlbk5hbWUsIHRocmVzaG9sZCwgcmVzdWx0KTtcbiAgICAgICAgfVxuICAgICAgICBleGNsdWRlZFRva2VuSWRzPy5hZGQodG9rZW5JZCk7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMucXVvdGFCbG9ja2VkVG9rZW5JZHMuZGVsZXRlKHRva2VuSWQpKSB7XG4gICAgICAgIHRoaXMubG9nUXVvdGFSZWNvdmVyZWQodG9rZW5JZCwgdG9rZW5NZXRhZGF0YS5uYW1lID8/IHRva2VuTmFtZSwgdGhyZXNob2xkLCByZXN1bHQpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBsb2dRdW90YU92ZXJUaHJlc2hvbGQoXG4gICAgdG9rZW5JZDogbnVtYmVyLFxuICAgIHRva2VuTmFtZTogc3RyaW5nLFxuICAgIHRocmVzaG9sZDogbnVtYmVyLFxuICAgIHJlc3VsdDogRXh0cmFjdDxPcGVuQUlRdW90YVVzYWdlUmVzdWx0LCB7IGtpbmQ6IFwib2tcIiB9PixcbiAgKTogdm9pZCB7XG4gICAgbG9nZ2VyLmluZm8oXG4gICAgICBgcXVvdGFfdGhyZXNob2xkIGdhdGU6IG92ZXJfdGhyZXNob2xkICR7dG9rZW5OYW1lfVske3Rva2VuSWR9XSAoJHtyZXN1bHQudXRpbGl6YXRpb25QY3R9JSA+PSAke3RocmVzaG9sZH0lKWAsXG4gICAgICB7XG4gICAgICAgIHRva2VuSWQsXG4gICAgICAgIHRva2VuTmFtZSxcbiAgICAgICAgcHJvdmlkZXI6IFwib3BlbmFpXCIsXG4gICAgICAgIHRocmVzaG9sZCxcbiAgICAgICAgY2FjaGVkVXRpbGl6YXRpb246IHJlc3VsdC51dGlsaXphdGlvblBjdCxcbiAgICAgICAgY2FjaGVBZ2U6IHJlc3VsdC5jYWNoZUFnZU1zLFxuICAgICAgICB3aW5kb3dEdXJhdGlvbk1pbnM6IHJlc3VsdC53aW5kb3dEdXJhdGlvbk1pbnMsXG4gICAgICAgIHJlc2V0c0F0OiByZXN1bHQucmVzZXRzQXQsXG4gICAgICAgIGxpbWl0SWQ6IHJlc3VsdC5saW1pdElkLFxuICAgICAgICByZWFzb246IFwib3Zlcl90aHJlc2hvbGRcIixcbiAgICAgIH0sXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgbG9nUXVvdGFSZWNvdmVyZWQoXG4gICAgdG9rZW5JZDogbnVtYmVyLFxuICAgIHRva2VuTmFtZTogc3RyaW5nLFxuICAgIHRocmVzaG9sZDogbnVtYmVyLFxuICAgIHJlc3VsdDogRXh0cmFjdDxPcGVuQUlRdW90YVVzYWdlUmVzdWx0LCB7IGtpbmQ6IFwib2tcIiB9PixcbiAgKTogdm9pZCB7XG4gICAgbG9nZ2VyLmluZm8oXG4gICAgICBgcXVvdGFfdGhyZXNob2xkIGdhdGU6IHJlY292ZXJlZCAke3Rva2VuTmFtZX1bJHt0b2tlbklkfV0gKCR7cmVzdWx0LnV0aWxpemF0aW9uUGN0fSUgPCAke3RocmVzaG9sZH0lKWAsXG4gICAgICB7XG4gICAgICAgIHRva2VuSWQsXG4gICAgICAgIHRva2VuTmFtZSxcbiAgICAgICAgcHJvdmlkZXI6IFwib3BlbmFpXCIsXG4gICAgICAgIHRocmVzaG9sZCxcbiAgICAgICAgY2FjaGVkVXRpbGl6YXRpb246IHJlc3VsdC51dGlsaXphdGlvblBjdCxcbiAgICAgICAgY2FjaGVBZ2U6IHJlc3VsdC5jYWNoZUFnZU1zLFxuICAgICAgICB3aW5kb3dEdXJhdGlvbk1pbnM6IHJlc3VsdC53aW5kb3dEdXJhdGlvbk1pbnMsXG4gICAgICAgIHJlc2V0c0F0OiByZXN1bHQucmVzZXRzQXQsXG4gICAgICAgIGxpbWl0SWQ6IHJlc3VsdC5saW1pdElkLFxuICAgICAgICByZWFzb246IFwicmVjb3ZlcmVkXCIsXG4gICAgICB9LFxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIGxvZ1F1b3RhTG9va3VwRmFpbE9wZW4odG9rZW5JZDogbnVtYmVyLCB0b2tlbk5hbWU6IHN0cmluZywgcmVhc29uOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCB0aHJlc2hvbGQgPSB0aGlzLmdldFF1b3RhVGhyZXNob2xkKHRva2VuSWQpO1xuICAgIGxvZ2dlci53YXJuKFwicXVvdGFfdGhyZXNob2xkIGdhdGU6IGxvb2t1cF9mYWlsX29wZW5cIiwge1xuICAgICAgdG9rZW5JZCxcbiAgICAgIHRva2VuTmFtZSxcbiAgICAgIHByb3ZpZGVyOiBcIm9wZW5haVwiLFxuICAgICAgdGhyZXNob2xkLFxuICAgICAgcmVhc29uOiBcImxvb2t1cF9mYWlsX29wZW5cIixcbiAgICAgIGxvb2t1cFJlYXNvbjogcmVhc29uLFxuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSB0aHJvd1F1b3RhVGhyZXNob2xkRXhjZWVkZWQoZWxpZ2liaWxpdHk6IFRva2VuRWxpZ2liaWxpdHkpOiBuZXZlciB7XG4gICAgbG9nZ2VyLndhcm4oXCJxdW90YV90aHJlc2hvbGQgZ2F0ZTogYWxsX2V4Y2VlZGVkXCIsIHtcbiAgICAgIHByb3ZpZGVyOiBcIm9wZW5haVwiLFxuICAgICAgdG9rZW5Db3VudDogZWxpZ2liaWxpdHkucmVhZHlBY3RpdmVUb2tlbklkcy5zaXplLFxuICAgICAgdGhyZXNob2xkZWRUb2tlbkNvdW50OiBlbGlnaWJpbGl0eS50aHJlc2hvbGRlZFRva2VuQ291bnQsXG4gICAgICBvdmVyVGhyZXNob2xkVG9rZW5zOiBlbGlnaWJpbGl0eS5vdmVyVGhyZXNob2xkVG9rZW5zLFxuICAgICAgcmVhc29uOiBcImFsbF9leGNlZWRlZFwiLFxuICAgIH0pO1xuICAgIHRocm93IG5ldyBRdW90YVRocmVzaG9sZEV4Y2VlZGVkRXJyb3IoXG4gICAgICBxdW90YVRocmVzaG9sZEV4Y2VlZGVkTWVzc2FnZShcIm9wZW5haVwiLCBlbGlnaWJpbGl0eS5vdmVyVGhyZXNob2xkVG9rZW5zKSxcbiAgICApO1xuICB9XG5cbiAgLy8g4pSA4pSAIEJyb3dzZXIgbG9naW4gZmxvdyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuICBwZW5kaW5nTG9naW46IHtcbiAgICB3b3JrZXI6IENvZGV4QXBwU2VydmVyV29ya2VyO1xuICAgIG5hbWU6IHN0cmluZztcbiAgICB0aW1lcjogUmV0dXJuVHlwZTx0eXBlb2Ygc2V0VGltZW91dD47XG4gIH0gfCBudWxsID0gbnVsbDtcblxuICBhc3luYyBzdGFydEJyb3dzZXJMb2dpbihuYW1lOiBzdHJpbmcpOiBQcm9taXNlPHsgYXV0aFVybDogc3RyaW5nIH0+IHtcbiAgICBpZiAodGhpcy5wZW5kaW5nTG9naW4pIHtcbiAgICAgIHRoaXMucGVuZGluZ0xvZ2luLndvcmtlci5raWxsKCkuY2F0Y2goKCkgPT4ge30pO1xuICAgICAgY2xlYXJUaW1lb3V0KHRoaXMucGVuZGluZ0xvZ2luLnRpbWVyKTtcbiAgICAgIHRoaXMucGVuZGluZ0xvZ2luID0gbnVsbDtcbiAgICB9XG5cbiAgICBjb25zdCB0ZW1wSWQgPSBEYXRlLm5vdygpO1xuICAgIGNvbnN0IHdvcmtlciA9IG5ldyBDb2RleEFwcFNlcnZlcldvcmtlcih7XG4gICAgICB0b2tlbklkOiB0ZW1wSWQsXG4gICAgICB0b2tlbk5hbWU6IG5hbWUsXG4gICAgICBhY2Nlc3NUb2tlbjogXCJcIixcbiAgICAgIGFjY291bnRJZDogXCJcIixcbiAgICB9KTtcblxuICAgIGNvbnN0IGF1dGhVcmwgPSBhd2FpdCB3b3JrZXIuc3RhcnRCcm93c2VyTG9naW4oKTtcblxuICAgIGNvbnN0IHRpbWVyID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICBpZiAodGhpcy5wZW5kaW5nTG9naW4/LndvcmtlciA9PT0gd29ya2VyKSB7XG4gICAgICAgIGxvZ2dlci53YXJuKGBicm93c2VyIGxvZ2luIHRpbWVvdXQgZm9yICR7bmFtZX0sIGtpbGxpbmcgd29ya2VyYCk7XG4gICAgICAgIHdvcmtlci5raWxsKCkuY2F0Y2goKCkgPT4ge30pO1xuICAgICAgICB0aGlzLnBlbmRpbmdMb2dpbiA9IG51bGw7XG4gICAgICB9XG4gICAgfSwgMzAwXzAwMCk7XG5cbiAgICB0aGlzLnBlbmRpbmdMb2dpbiA9IHsgd29ya2VyLCBuYW1lLCB0aW1lciB9O1xuICAgIHJldHVybiB7IGF1dGhVcmwgfTtcbiAgfVxuXG4gIGdldCBwZW5kaW5nTG9naW5OYW1lKCk6IHN0cmluZyB8IG51bGwge1xuICAgIHJldHVybiB0aGlzLnBlbmRpbmdMb2dpbj8ubmFtZSA/PyBudWxsO1xuICB9XG5cbiAgYXN5bmMgY29tcGxldGVCcm93c2VyTG9naW4oKTogUHJvbWlzZTx7XG4gICAgYWNjZXNzVG9rZW46IHN0cmluZztcbiAgICByZWZyZXNoVG9rZW46IHN0cmluZztcbiAgICBpZFRva2VuPzogc3RyaW5nO1xuICAgIGFjY291bnRJZDogc3RyaW5nO1xuICB9PiB7XG4gICAgaWYgKCF0aGlzLnBlbmRpbmdMb2dpbikgdGhyb3cgbmV3IEVycm9yKFwibm8gcGVuZGluZyBsb2dpblwiKTtcbiAgICBjb25zdCB7IHdvcmtlciwgdGltZXIgfSA9IHRoaXMucGVuZGluZ0xvZ2luO1xuXG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHdvcmtlci53YWl0Rm9yQnJvd3NlckxvZ2luQ29tcGxldGUoKTtcbiAgICAgIGNvbnN0IGNyZWRzID0gYXdhaXQgd29ya2VyLnJlYWRNYW5hZ2VkQ3JlZGVudGlhbHMoKTtcbiAgICAgIGlmICghY3JlZHMpIHRocm93IG5ldyBFcnJvcihcImZhaWxlZCB0byByZWFkIGNyZWRlbnRpYWxzIGFmdGVyIGxvZ2luXCIpO1xuICAgICAgcmV0dXJuIGNyZWRzO1xuICAgIH0gZmluYWxseSB7XG4gICAgICBjbGVhclRpbWVvdXQodGltZXIpO1xuICAgICAgdGhpcy5wZW5kaW5nTG9naW4gPSBudWxsO1xuICAgICAgYXdhaXQgd29ya2VyLmtpbGwoKS5jYXRjaCgoKSA9PiB7fSk7XG4gICAgfVxuICB9XG5cbiAgLy8g4pSA4pSAIFN0YXRzIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIGdldCB3b3JrZXJDb3VudCgpOiBudW1iZXIge1xuICAgIHJldHVybiBbLi4udGhpcy53b3JrZXJQb29sLnZhbHVlcygpXS5mbGF0KCkubGVuZ3RoO1xuICB9XG5cbiAgZ2V0IHJlYWR5V29ya2VyQ291bnQoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gWy4uLnRoaXMud29ya2VyUG9vbC52YWx1ZXMoKV0uZmxhdCgpLmZpbHRlcigodykgPT4gdy5pc1JlYWR5KS5sZW5ndGg7XG4gIH1cblxuICBnZXQgcXVldWVMZW5ndGgoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5xdWV1ZS5sZW5ndGg7XG4gIH1cblxuICAvLyBNb25pdCDtkZzsi5zsmqkg4oCUIO2GoO2BsOuzhCDtmITsnqwg7JuM7LukIOyImCDsiqTrg4Xsg7cgKOydtOumhOyInCDsoJXroKwpXG4gIGdldCB3b3JrZXJDb3VudHNCeVRva2VuKCk6IEFycmF5PHsgbmFtZTogc3RyaW5nOyBjb3VudDogbnVtYmVyIH0+IHtcbiAgICByZXR1cm4gWy4uLnRoaXMud29ya2VyUG9vbC5lbnRyaWVzKCldXG4gICAgICAubWFwKChbdG9rZW5JZCwgd29ya2Vyc10pID0+ICh7XG4gICAgICAgIG5hbWU6IHdvcmtlcnNbMF0/LnRva2VuTmFtZSA/PyBgdG9rZW4gJHt0b2tlbklkfWAsXG4gICAgICAgIGNvdW50OiB3b3JrZXJzLmxlbmd0aCxcbiAgICAgIH0pKVxuICAgICAgLmZpbHRlcigoZW50cnkpID0+IGVudHJ5LmNvdW50ID4gMClcbiAgICAgIC50b1NvcnRlZCgoYSwgYikg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
|
|
441
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3BlbmFpLWRpc3BhdGNoZXIuanMiLCJuYW1lcyI6W10sInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL3V0aWxzL3Byb3ZpZGVycy9vcGVuYWkvb3BlbmFpLWRpc3BhdGNoZXIudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgZ2V0TG9nZ2VyIH0gZnJvbSBcIkBsb2d0YXBlL2xvZ3RhcGVcIjtcblxuaW1wb3J0IHsgUXVvdGFUaHJlc2hvbGRFeGNlZWRlZEVycm9yIH0gZnJvbSBcIi4uLy4uLy4uL2FwcGxpY2F0aW9uL3FncmlkL3FncmlkLnR5cGVzXCI7XG5pbXBvcnQgeyBUb2tlbk1vZGVsIH0gZnJvbSBcIi4uLy4uLy4uL2FwcGxpY2F0aW9uL3Rva2VuL3Rva2VuLm1vZGVsXCI7XG5pbXBvcnQgeyB0eXBlIE9wZW5BSUNyZWRlbnRpYWxzIH0gZnJvbSBcIi4uLy4uLy4uL2FwcGxpY2F0aW9uL3Rva2VuL3Rva2VuLnR5cGVzXCI7XG5pbXBvcnQge1xuICB0eXBlIEdlbmVyYXRlUmVxdWVzdCxcbiAgdHlwZSBHZW5lcmF0ZVJlc3VsdCxcbiAgdHlwZSBHZW5lcmF0ZVN0cmVhbUNhbGxiYWNrcyxcbiAgdHlwZSBHZW5lcmF0ZWRJbWFnZSxcbiAgdHlwZSBQcm92aWRlckRpc3BhdGNoZXIsXG59IGZyb20gXCIuLi9jb21tb24vcHJvdmlkZXItZGlzcGF0Y2hlclwiO1xuaW1wb3J0IHsgU21vb3RoV2VpZ2h0ZWRSb3VuZFJvYmluIH0gZnJvbSBcIi4uL2NvbW1vbi9zbW9vdGgtd2VpZ2h0ZWQtcm91bmQtcm9iaW5cIjtcbmltcG9ydCB7XG4gIHR5cGUgSnNvblZhbHVlLFxuICB0eXBlIE9wZW5BSVJlc3BvbnNlSXRlbSxcbiAgdHlwZSBPcGVuQUlSZXNwb25zZXNPcHRpb25zLFxufSBmcm9tIFwiLi9vcGVuYWktYmFja2VuZC1wcm90b2NvbFwiO1xuaW1wb3J0IHsgT3BlbkFJRGlyZWN0Q2xpZW50LCB0eXBlIE9wZW5BSURpcmVjdENsaWVudE9wdGlvbnMgfSBmcm9tIFwiLi9vcGVuYWktZGlyZWN0LWNsaWVudFwiO1xuaW1wb3J0IHsgcmVhZE9wZW5BSVF1b3RhVXNhZ2UsIHR5cGUgT3BlbkFJUmF0ZUxpbWl0c1dpdGhNZXRhIH0gZnJvbSBcIi4vb3BlbmFpLXF1b3RhXCI7XG5pbXBvcnQgeyBoYW5kbGVDaGF0Z3B0QXV0aFRva2Vuc1JlZnJlc2ggfSBmcm9tIFwiLi9vcGVuYWktcmVmcmVzaFwiO1xuaW1wb3J0IHsgdHlwZSBPcGVuQUlUcmFuc3BvcnRLaW5kLCByZXNvbHZlT3BlbkFJVHJhbnNwb3J0S2luZCB9IGZyb20gXCIuL29wZW5haS10cmFuc3BvcnQtY29uZmlnXCI7XG5cbmNvbnN0IGxvZ2dlciA9IGdldExvZ2dlcihbXCJxZ3JpZFwiLCBcIm9wZW5haS1kaXNwYXRjaGVyXCJdKTtcbi8vIOq1kOyytOuQnCBjb2RleCB3b3JrZXIg6rCAIOqwleygnO2VmOuNmCB3YXRjaGRvZy4g7Zi47Lac7J6Q6rCAIHRpbWVvdXRNcyDrpbwg7IOd65617ZW064+EIOyalOyyreydtFxuLy8g7JiB7JuQ7Z6IIOunpOuLrOumrOyngCDslYrrj4TroZ0gZGlyZWN0IHRyYW5zcG9ydCDrj4Qg7Jyg7ZWc7ZWcIOq4sOuzuCDsg4HtlZzsnYQg7Jyg7KeA7ZWc64ukLlxuY29uc3QgREVGQVVMVF9SRVFVRVNUX1RJTUVPVVRfTVMgPSA2MDBfMDAwO1xuXG5leHBvcnQgdHlwZSBJbWFnZUZhaWx1cmVLaW5kID0gXCJnYXRlXCIgfCBcIm5vdF9jYWxsZWRcIiB8IFwiaW5jb21wbGV0ZVwiO1xuXG5leHBvcnQgY2xhc3MgSW1hZ2VHZW5lcmF0aW9uRXJyb3IgZXh0ZW5kcyBFcnJvciB7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHJlYWRvbmx5IGtpbmQ6IEltYWdlRmFpbHVyZUtpbmQsXG4gICAgbWVzc2FnZTogc3RyaW5nLFxuICApIHtcbiAgICBzdXBlcihtZXNzYWdlKTtcbiAgICB0aGlzLm5hbWUgPSBcIkltYWdlR2VuZXJhdGlvbkVycm9yXCI7XG4gIH1cbn1cblxudHlwZSBUb2tlbk1ldGFkYXRhID0ge1xuICBuYW1lOiBzdHJpbmc7XG4gIGNyZWRlbnRpYWxzOiBPcGVuQUlDcmVkZW50aWFscztcbiAgcXVvdGFUaHJlc2hvbGQ/OiBudW1iZXIgfCBudWxsO1xuICB3ZWlnaHQ6IG51bWJlcjtcbiAgYWN0aXZlOiBib29sZWFuO1xuICBnZW5lcmF0aW9uOiBudW1iZXI7XG59O1xuXG50eXBlIFRva2VuU2VsZWN0aW9uID0geyB0b2tlbklkOiBudW1iZXI7IG1ldGFkYXRhOiBUb2tlbk1ldGFkYXRhIH07XG5cbmV4cG9ydCB0eXBlIE9wZW5BSURpcmVjdENsaWVudEZhY3RvcnkgPSAoXG4gIG9wdGlvbnM6IE9wZW5BSURpcmVjdENsaWVudE9wdGlvbnMsXG4gIHRva2VuSWQ6IG51bWJlcixcbikgPT4gUGljazxPcGVuQUlEaXJlY3RDbGllbnQsIFwicmVzcG9uc2VzXCI+ICYgeyBjbG9zZT86ICgpID0+IHZvaWQgfTtcblxudHlwZSBDbGllbnRFbnRyeSA9IHtcbiAgZ2VuZXJhdGlvbjogbnVtYmVyO1xuICBjbGllbnQ6IFBpY2s8T3BlbkFJRGlyZWN0Q2xpZW50LCBcInJlc3BvbnNlc1wiPiAmIHsgY2xvc2U/OiAoKSA9PiB2b2lkIH07XG4gIGluRmxpZ2h0OiBudW1iZXI7XG4gIHJldGlyZWQ6IGJvb2xlYW47XG59O1xuXG5leHBvcnQgaW50ZXJmYWNlIE9wZW5BSURpc3BhdGNoZXJEZXBlbmRlbmNpZXMge1xuICBjbGllbnRGYWN0b3J5PzogT3BlbkFJRGlyZWN0Q2xpZW50RmFjdG9yeTtcbiAgZmV0Y2g/OiB0eXBlb2YgZmV0Y2g7XG59XG5cbmZ1bmN0aW9uIGFib3J0RXJyb3Ioc2lnbmFsOiBBYm9ydFNpZ25hbCk6IEVycm9yIHtcbiAgY29uc3QgcmVhc29uID0gc2lnbmFsLnJlYXNvbjtcbiAgcmV0dXJuIHJlYXNvbiBpbnN0YW5jZW9mIEVycm9yID8gcmVhc29uIDogbmV3IERPTUV4Y2VwdGlvbihcIkFib3J0ZWRcIiwgXCJBYm9ydEVycm9yXCIpO1xufVxuXG5mdW5jdGlvbiBhY3RpdmVTaWduYWwoc2lnbmFsPzogQWJvcnRTaWduYWwsIHRpbWVvdXRNcz86IG51bWJlcik6IEFib3J0U2lnbmFsIHtcbiAgY29uc3QgdGltZW91dCA9IEFib3J0U2lnbmFsLnRpbWVvdXQodGltZW91dE1zID8/IERFRkFVTFRfUkVRVUVTVF9USU1FT1VUX01TKTtcbiAgcmV0dXJuIHNpZ25hbCA/IEFib3J0U2lnbmFsLmFueShbc2lnbmFsLCB0aW1lb3V0XSkgOiB0aW1lb3V0O1xufVxuXG5mdW5jdGlvbiBxdW90YU1lc3NhZ2UoZW50cmllczogQXJyYXk8eyBuYW1lOiBzdHJpbmc7IHRocmVzaG9sZDogbnVtYmVyIH0+KTogc3RyaW5nIHtcbiAgY29uc3QgZGV0YWlsID0gZW50cmllcy5tYXAoKGUpID0+IGAke2UubmFtZX0gKHRocmVzaG9sZCAke2UudGhyZXNob2xkfSUpYCkuam9pbihcIiwgXCIpO1xuICByZXR1cm4gZGV0YWlsXG4gICAgPyBgQWxsIG9wZW5haSB0b2tlbnMgZXhjZWVkZWQgcXVvdGEgdGhyZXNob2xkOiAke2RldGFpbH1gXG4gICAgOiBcIkFsbCBvcGVuYWkgdG9rZW5zIGV4Y2VlZGVkIHF1b3RhIHRocmVzaG9sZFwiO1xufVxuXG5mdW5jdGlvbiBpbnB1dEl0ZW1zKHJlcTogR2VuZXJhdGVSZXF1ZXN0KTogT3BlbkFJUmVzcG9uc2VJdGVtW10ge1xuICBjb25zdCBoaXN0b3J5ID0gKHJlcS5jb2xkSGlzdG9yeSA/PyBbXSkgYXMgT3BlbkFJUmVzcG9uc2VJdGVtW107XG4gIGNvbnN0IGNvbnRlbnQ6IE9wZW5BSVJlc3BvbnNlSXRlbVtdID0gcmVxLmNvbGRJbnB1dC5tYXAoKGlucHV0KSA9PiB7XG4gICAgaWYgKGlucHV0LnR5cGUgPT09IFwidGV4dFwiKSByZXR1cm4geyB0eXBlOiBcImlucHV0X3RleHRcIiwgdGV4dDogaW5wdXQudGV4dCB9O1xuICAgIGlmIChpbnB1dC50eXBlID09PSBcImltYWdlXCIpIHJldHVybiB7IHR5cGU6IFwiaW5wdXRfaW1hZ2VcIiwgaW1hZ2VfdXJsOiBpbnB1dC51cmwgfTtcbiAgICBpZiAoaW5wdXQudHlwZSA9PT0gXCJsb2NhbEltYWdlXCIpIHJldHVybiB7IHR5cGU6IFwiaW5wdXRfaW1hZ2VcIiwgaW1hZ2VfdXJsOiBpbnB1dC5wYXRoIH07XG4gICAgcmV0dXJuIHsgdHlwZTogXCJpbnB1dF90ZXh0XCIsIHRleHQ6IGAke2lucHV0Lm5hbWV9OiAke2lucHV0LnBhdGh9YCB9O1xuICB9KTtcbiAgcmV0dXJuIFsuLi5oaXN0b3J5LCB7IHR5cGU6IFwibWVzc2FnZVwiLCByb2xlOiBcInVzZXJcIiwgY29udGVudCB9XTtcbn1cblxuZnVuY3Rpb24gYXNSZWFzb25pbmcocmVxOiBHZW5lcmF0ZVJlcXVlc3QpOiBPcGVuQUlSZXNwb25zZXNPcHRpb25zW1wicmVhc29uaW5nXCJdIHwgdW5kZWZpbmVkIHtcbiAgY29uc3Qgc3VtbWFyeSA9XG4gICAgcmVxLnJlYXNvbmluZ1N1bW1hcnkgJiYgcmVxLnJlYXNvbmluZ1N1bW1hcnkgIT09IFwibm9uZVwiID8gcmVxLnJlYXNvbmluZ1N1bW1hcnkgOiB1bmRlZmluZWQ7XG4gIGlmICghcmVxLmVmZm9ydCAmJiAhc3VtbWFyeSkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgcmV0dXJuIHtcbiAgICAuLi4ocmVxLmVmZm9ydFxuICAgICAgPyB7IGVmZm9ydDogcmVxLmVmZm9ydCBhcyBOb25OdWxsYWJsZTxPcGVuQUlSZXNwb25zZXNPcHRpb25zW1wicmVhc29uaW5nXCJdPltcImVmZm9ydFwiXSB9XG4gICAgICA6IHt9KSxcbiAgICAuLi4oc3VtbWFyeVxuICAgICAgPyB7XG4gICAgICAgICAgc3VtbWFyeTogc3VtbWFyeSBhcyBOb25OdWxsYWJsZTxPcGVuQUlSZXNwb25zZXNPcHRpb25zW1wicmVhc29uaW5nXCJdPltcInN1bW1hcnlcIl0sXG4gICAgICAgIH1cbiAgICAgIDoge30pLFxuICB9O1xufVxuXG5mdW5jdGlvbiByZXF1ZXN0T3B0aW9ucyhyZXE6IEdlbmVyYXRlUmVxdWVzdCk6IE9wZW5BSVJlc3BvbnNlc09wdGlvbnMge1xuICByZXR1cm4ge1xuICAgIG1vZGVsOiByZXEubW9kZWwgPz8gXCJcIixcbiAgICAuLi4ocmVxLnN5c3RlbVByb21wdCA/IHsgaW5zdHJ1Y3Rpb25zOiByZXEuc3lzdGVtUHJvbXB0IH0gOiB7fSksXG4gICAgaGlzdG9yeTogaW5wdXRJdGVtcyhyZXEpLFxuICAgIC4uLihhc1JlYXNvbmluZyhyZXEpID8geyByZWFzb25pbmc6IGFzUmVhc29uaW5nKHJlcSkgfSA6IHt9KSxcbiAgICAuLi4ocmVxLnZlcmJvc2l0eSA/IHsgdmVyYm9zaXR5OiByZXEudmVyYm9zaXR5IGFzIE9wZW5BSVJlc3BvbnNlc09wdGlvbnNbXCJ2ZXJib3NpdHlcIl0gfSA6IHt9KSxcbiAgICAuLi4ocmVxLnNlcnZpY2VUaWVyXG4gICAgICA/IHsgc2VydmljZVRpZXI6IHJlcS5zZXJ2aWNlVGllciA9PT0gXCJmYXN0XCIgPyBcInByaW9yaXR5XCIgOiByZXEuc2VydmljZVRpZXIgfVxuICAgICAgOiB7fSksXG4gICAgLi4uKHJlcS5wcm9tcHRDYWNoZUtleSA/IHsgcHJvbXB0Q2FjaGVLZXk6IHJlcS5wcm9tcHRDYWNoZUtleSB9IDoge30pLFxuICAgIC4uLihyZXEub3V0cHV0U2NoZW1hID8geyBvdXRwdXRTY2hlbWE6IHsgc2NoZW1hOiByZXEub3V0cHV0U2NoZW1hIGFzIEpzb25WYWx1ZSB9IH0gOiB7fSksXG4gICAgLi4uKHJlcS5pbWFnZUdlbmVyYXRpb25cbiAgICAgID8geyBpbWFnZUdlbmVyYXRpb246IHJlcS5pbWFnZUdlbmVyYXRpb25PcHRpb25zID8geyAuLi5yZXEuaW1hZ2VHZW5lcmF0aW9uT3B0aW9ucyB9IDogdHJ1ZSB9XG4gICAgICA6IHt9KSxcbiAgfTtcbn1cblxuLyoqXG4gKiBEaXJlY3QgT3BlbkFJIGRpc3BhdGNoZXIg4oCUIEFudGhyb3BpYyDqs7wg64+Z7J287ZWcIHN0YXRlbGVzcyDsi6Ttlokg66qo6424LlxuICpcbiAqIOyalOyyrSA9IO2GoO2BsCDshKDtg50ocXVvdGEgZ2F0ZSArIHdlaWdodGVkIHJvdW5kLXJvYmluICsgY2FjaGUgYWZmaW5pdHkg7ISg7Zi4KSDihpIgSFRUUFMvV1NcbiAqIOyghOyGoS4gcGVybWl0L+2BkCDqsJnsnYAg64+Z7Iuc7ISxIOyDge2VnOydgCDrkZDsp4Ag7JWK64qU64ukOiDsoITshqHsnYAgZmV0Y2gg7ZWcIOuyiOydtOudvCDroZzsu6wg7J6Q7JuQ7J20XG4gKiDtnazshoztlZjsp4Ag7JWK6rOgLCDsg4HrpZgg7KCc7ZWc7J2AIOuwseyXlOuTnOydmCDsnZHri7UoNDI5IOuTsSnsnbQg7KeE7Iuk7J2064ukLiB3b3JrZXIgcG9vbCDsi5zsoIjsnZhcbiAqIO2BkCDsnZjrr7jroaAoU0VSVkVSX0JVU1ksIO2BkCDtg4DsnoTslYTsm4Mp7J2AIOydtCDsoITtmZjsnLzroZwg7KCc6rGw65CQ64ukLlxuICovXG5leHBvcnQgY2xhc3MgT3BlbkFJRGlzcGF0Y2hlciBpbXBsZW1lbnRzIFByb3ZpZGVyRGlzcGF0Y2hlciB7XG4gIHJlYWRvbmx5IHRva2VuTWV0YWRhdGEgPSBuZXcgTWFwPG51bWJlciwgVG9rZW5NZXRhZGF0YT4oKTtcbiAgcmVhZG9ubHkgdHJhbnNwb3J0S2luZDogT3BlbkFJVHJhbnNwb3J0S2luZDtcbiAgcmVhZG9ubHkgcmF0ZUxpbWl0c0NhY2hlID0gbmV3IE1hcDxudW1iZXIsIE9wZW5BSVJhdGVMaW1pdHNXaXRoTWV0YSAmIHsgZ2VuZXJhdGlvbjogbnVtYmVyIH0+KCk7XG4gIHByaXZhdGUgcmVhZG9ubHkgcGVuZGluZ1JhdGVMaW1pdHMgPSBuZXcgTWFwPFxuICAgIG51bWJlcixcbiAgICBQcm9taXNlPE9wZW5BSVJhdGVMaW1pdHNXaXRoTWV0YSAmIHsgZ2VuZXJhdGlvbjogbnVtYmVyIH0+XG4gID4oKTtcbiAgcHJpdmF0ZSByZWFkb25seSBjbGllbnRzID0gbmV3IE1hcDxudW1iZXIsIENsaWVudEVudHJ5PigpO1xuICBwcml2YXRlIHJlYWRvbmx5IHJldGlyZWRDbGllbnRzID0gbmV3IFNldDxDbGllbnRFbnRyeT4oKTtcbiAgc3RhdGljIHJlYWRvbmx5IFJBVEVfTElNSVRTX0NBQ0hFX1RUTCA9IDYwXzAwMDtcblxuICBwcml2YXRlIHJlYWRvbmx5IHNlbGVjdG9yID0gbmV3IFNtb290aFdlaWdodGVkUm91bmRSb2JpbigpO1xuICBwcml2YXRlIHJlYWRvbmx5IGNsaWVudEZhY3Rvcnk6IE9wZW5BSURpcmVjdENsaWVudEZhY3Rvcnk7XG4gIHByaXZhdGUgcmVhZG9ubHkgZmV0Y2hJbXBsOiB0eXBlb2YgZmV0Y2g7XG4gIHByaXZhdGUgcmVhZG9ubHkgcXVvdGFCbG9ja2VkID0gbmV3IFNldDxudW1iZXI+KCk7XG4gIHByaXZhdGUgaW5GbGlnaHRDb3VudCA9IDA7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgdHJhbnNwb3J0S2luZDogT3BlbkFJVHJhbnNwb3J0S2luZCA9IHJlc29sdmVPcGVuQUlUcmFuc3BvcnRLaW5kKCksXG4gICAgZGVwZW5kZW5jaWVzOiBPcGVuQUlEaXNwYXRjaGVyRGVwZW5kZW5jaWVzID0ge30sXG4gICkge1xuICAgIHRoaXMudHJhbnNwb3J0S2luZCA9IHRyYW5zcG9ydEtpbmQ7XG4gICAgdGhpcy5jbGllbnRGYWN0b3J5ID1cbiAgICAgIGRlcGVuZGVuY2llcy5jbGllbnRGYWN0b3J5ID8/ICgob3B0aW9ucykgPT4gbmV3IE9wZW5BSURpcmVjdENsaWVudChvcHRpb25zKSk7XG4gICAgdGhpcy5mZXRjaEltcGwgPSBkZXBlbmRlbmNpZXMuZmV0Y2ggPz8gZmV0Y2g7XG4gIH1cblxuICBhc3luYyBzdGFydCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCB7IHJvd3MgfSA9IGF3YWl0IFRva2VuTW9kZWwuZmluZE1hbnkoXCJBXCIpO1xuICAgIGZvciAoY29uc3Qgcm93IG9mIHJvd3MpIHtcbiAgICAgIGlmIChyb3cucHJvdmlkZXIgIT09IFwib3BlbmFpXCIpIGNvbnRpbnVlO1xuICAgICAgdGhpcy5zZXRUb2tlbihcbiAgICAgICAgcm93LmlkLFxuICAgICAgICByb3cubmFtZSxcbiAgICAgICAgcm93LmNyZWRlbnRpYWxzIGFzIE9wZW5BSUNyZWRlbnRpYWxzLFxuICAgICAgICByb3cucXVvdGFfdGhyZXNob2xkLFxuICAgICAgICByb3cud2VpZ2h0LFxuICAgICAgICByb3cuYWN0aXZlLFxuICAgICAgKTtcbiAgICB9XG4gICAgbG9nZ2VyLmluZm8oYHN0YXJ0ZWQgZGlyZWN0IE9wZW5BSSBydW50aW1lIHdpdGggJHt0aGlzLnRva2VuTWV0YWRhdGEuc2l6ZX0gdG9rZW5zYCk7XG4gIH1cblxuICBhc3luYyBzdG9wKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGZvciAoY29uc3QgeyBjbGllbnQgfSBvZiB0aGlzLmNsaWVudHMudmFsdWVzKCkpIGNsaWVudC5jbG9zZT8uKCk7XG4gICAgdGhpcy5jbGllbnRzLmNsZWFyKCk7XG4gICAgZm9yIChjb25zdCBlbnRyeSBvZiB0aGlzLnJldGlyZWRDbGllbnRzKSBlbnRyeS5jbGllbnQuY2xvc2U/LigpO1xuICAgIHRoaXMucmV0aXJlZENsaWVudHMuY2xlYXIoKTtcbiAgICB0aGlzLnRva2VuTWV0YWRhdGEuY2xlYXIoKTtcbiAgICB0aGlzLnJhdGVMaW1pdHNDYWNoZS5jbGVhcigpO1xuICAgIHRoaXMucXVvdGFCbG9ja2VkLmNsZWFyKCk7XG4gICAgdGhpcy5zZWxlY3Rvci5yZXNldFNjb3JlcygpO1xuICB9XG5cbiAgYXN5bmMgb25Ub2tlbkFkZGVkKFxuICAgIGlkOiBudW1iZXIsXG4gICAgbmFtZTogc3RyaW5nLFxuICAgIGNyZWRlbnRpYWxzOiBPcGVuQUlDcmVkZW50aWFscyxcbiAgICBxdW90YVRocmVzaG9sZD86IG51bWJlciB8IG51bGwsXG4gICAgd2VpZ2h0ID0gMSxcbiAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdGhpcy5zZXRUb2tlbihpZCwgbmFtZSwgY3JlZGVudGlhbHMsIHF1b3RhVGhyZXNob2xkLCB3ZWlnaHQsIHRydWUpO1xuICB9XG5cbiAgYXN5bmMgb25Ub2tlblVwZGF0ZWQoXG4gICAgaWQ6IG51bWJlcixcbiAgICBuYW1lOiBzdHJpbmcsXG4gICAgY3JlZGVudGlhbHM6IE9wZW5BSUNyZWRlbnRpYWxzLFxuICAgIHF1b3RhVGhyZXNob2xkPzogbnVtYmVyIHwgbnVsbCxcbiAgICB3ZWlnaHQgPSAxLFxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBvbGQgPSB0aGlzLnRva2VuTWV0YWRhdGEuZ2V0KGlkKTtcbiAgICB0aGlzLnNldFRva2VuKGlkLCBuYW1lLCBjcmVkZW50aWFscywgcXVvdGFUaHJlc2hvbGQsIHdlaWdodCwgb2xkPy5hY3RpdmUgPz8gdHJ1ZSk7XG4gIH1cblxuICBhc3luYyBvblRva2VuUmVtb3ZlZChpZDogbnVtYmVyKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdGhpcy5yZXRpcmVDbGllbnQoaWQpO1xuICAgIHRoaXMudG9rZW5NZXRhZGF0YS5kZWxldGUoaWQpO1xuICAgIHRoaXMuc2VsZWN0b3IucmVtb3ZlVG9rZW4oaWQpO1xuICAgIHRoaXMuaW52YWxpZGF0ZVJhdGVMaW1pdHNDYWNoZShpZCk7XG4gICAgdGhpcy5xdW90YUJsb2NrZWQuZGVsZXRlKGlkKTtcbiAgfVxuXG4gIG9uVG9rZW5EZWFjdGl2YXRlZChpZDogbnVtYmVyKTogdm9pZCB7XG4gICAgY29uc3QgdG9rZW4gPSB0aGlzLnRva2VuTWV0YWRhdGEuZ2V0KGlkKTtcbiAgICBpZiAodG9rZW4pIHRva2VuLmFjdGl2ZSA9IGZhbHNlO1xuICAgIHRoaXMuc2VsZWN0b3IucmVzZXRTY29yZXMoKTtcbiAgfVxuXG4gIG9uVG9rZW5BY3RpdmF0ZWQoaWQ6IG51bWJlcik6IHZvaWQge1xuICAgIGNvbnN0IHRva2VuID0gdGhpcy50b2tlbk1ldGFkYXRhLmdldChpZCk7XG4gICAgaWYgKHRva2VuKSB0b2tlbi5hY3RpdmUgPSB0cnVlO1xuICAgIHRoaXMuc2VsZWN0b3IucmVzZXRTY29yZXMoKTtcbiAgfVxuXG4gIGFzeW5jIHJlcGxhY2VUb2tlbnMoXG4gICAgcm93czogQXJyYXk8e1xuICAgICAgaWQ6IG51bWJlcjtcbiAgICAgIG5hbWU6IHN0cmluZztcbiAgICAgIGNyZWRlbnRpYWxzOiBPcGVuQUlDcmVkZW50aWFscztcbiAgICAgIHF1b3RhVGhyZXNob2xkPzogbnVtYmVyIHwgbnVsbDtcbiAgICAgIHdlaWdodDogbnVtYmVyO1xuICAgIH0+LFxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBpZHMgPSBuZXcgU2V0KHJvd3MubWFwKChyKSA9PiByLmlkKSk7XG4gICAgZm9yIChjb25zdCBpZCBvZiB0aGlzLnRva2VuTWV0YWRhdGEua2V5cygpKSBpZiAoIWlkcy5oYXMoaWQpKSBhd2FpdCB0aGlzLm9uVG9rZW5SZW1vdmVkKGlkKTtcbiAgICBmb3IgKGNvbnN0IHJvdyBvZiByb3dzKVxuICAgICAgYXdhaXQgdGhpcy5vblRva2VuVXBkYXRlZChyb3cuaWQsIHJvdy5uYW1lLCByb3cuY3JlZGVudGlhbHMsIHJvdy5xdW90YVRocmVzaG9sZCwgcm93LndlaWdodCk7XG4gIH1cblxuICBhc3luYyBnZW5lcmF0ZShyZXE6IEdlbmVyYXRlUmVxdWVzdCk6IFByb21pc2U8R2VuZXJhdGVSZXN1bHQ+IHtcbiAgICByZXR1cm4gdGhpcy5ydW4ocmVxKTtcbiAgfVxuXG4gIGFzeW5jIGdlbmVyYXRlU3RyZWFtKHJlcTogR2VuZXJhdGVSZXF1ZXN0LCBjYjogR2VuZXJhdGVTdHJlYW1DYWxsYmFja3MpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAocmVxLmltYWdlR2VuZXJhdGlvbilcbiAgICAgIHRocm93IG5ldyBJbWFnZUdlbmVyYXRpb25FcnJvcihcbiAgICAgICAgXCJnYXRlXCIsXG4gICAgICAgIFwiaW1hZ2UgZ2VuZXJhdGlvbiBpcyBub3Qgc3VwcG9ydGVkIG9uIHRoZSBzdHJlYW1pbmcgcGF0aFwiLFxuICAgICAgKTtcbiAgICB0cnkge1xuICAgICAgY2Iub25Db21wbGV0ZShhd2FpdCB0aGlzLnJ1bihyZXEsIGNiLm9uRGVsdGEpKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgY2Iub25FcnJvcihlcnJvciBhcyBFcnJvcik7XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9XG4gIH1cblxuICAvLyBnZW5lcmF0ZS9nZW5lcmF0ZVN0cmVhbSDqs7XthrUg7Iuk7ZaJIOKAlCDthqDtgbAg7ISg7YOd6rO8IGluLWZsaWdodCDsp5Hqs4Trpbwg7ZWcIOqzs+yXkCDrkZTri6QuXG4gIHByaXZhdGUgYXN5bmMgcnVuKFxuICAgIHJlcTogR2VuZXJhdGVSZXF1ZXN0LFxuICAgIG9uRGVsdGE/OiAodGV4dDogc3RyaW5nKSA9PiB2b2lkLFxuICApOiBQcm9taXNlPEdlbmVyYXRlUmVzdWx0PiB7XG4gICAgY29uc3Qgc2lnbmFsID0gYWN0aXZlU2lnbmFsKHJlcS5hYm9ydFNpZ25hbCwgcmVxLnRpbWVvdXRNcyk7XG4gICAgaWYgKHNpZ25hbC5hYm9ydGVkKSB0aHJvdyBhYm9ydEVycm9yKHNpZ25hbCk7XG4gICAgY29uc3Qgc2VsZWN0aW9uID0gYXdhaXQgdGhpcy5zZWxlY3RUb2tlbihyZXEucHJlZmVycmVkVG9rZW5JZCwgc2lnbmFsKTtcbiAgICB0aGlzLmluRmxpZ2h0Q291bnQrKztcbiAgICB0cnkge1xuICAgICAgaWYgKHNpZ25hbC5hYm9ydGVkKSB0aHJvdyBhYm9ydEVycm9yKHNpZ25hbCk7XG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy5ydW5EaXJlY3Qoc2VsZWN0aW9uLCB7IC4uLnJlcSwgYWJvcnRTaWduYWw6IHNpZ25hbCB9LCBvbkRlbHRhKTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgdGhpcy5pbkZsaWdodENvdW50LS07XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBydW5EaXJlY3QoXG4gICAgc2VsZWN0aW9uOiBUb2tlblNlbGVjdGlvbixcbiAgICByZXE6IEdlbmVyYXRlUmVxdWVzdCxcbiAgICBvbkRlbHRhPzogKHRleHQ6IHN0cmluZykgPT4gdm9pZCxcbiAgKTogUHJvbWlzZTxHZW5lcmF0ZVJlc3VsdD4ge1xuICAgIGNvbnN0IHN0YXJ0ZWRBdCA9IERhdGUubm93KCk7XG4gICAgbGV0IGZpcnN0RGVsdGFBdDogbnVtYmVyIHwgdW5kZWZpbmVkO1xuICAgIGxldCB0ZXh0ID0gXCJcIjtcbiAgICBsZXQgdXNhZ2UgPSB7XG4gICAgICB0b3RhbFRva2VuczogMCxcbiAgICAgIGlucHV0VG9rZW5zOiAwLFxuICAgICAgb3V0cHV0VG9rZW5zOiAwLFxuICAgICAgY2FjaGVkSW5wdXRUb2tlbnM6IDAsXG4gICAgICByZWFzb25pbmdPdXRwdXRUb2tlbnM6IDAsXG4gICAgfTtcbiAgICBjb25zdCBpbWFnZXM6IEdlbmVyYXRlZEltYWdlW10gPSBbXTtcbiAgICBsZXQgaW1hZ2VBdHRlbXB0ZWQgPSBmYWxzZTtcbiAgICBsZXQgc2VydmluZ01vZGVsID0gcmVxLm1vZGVsID8/IFwiXCI7XG4gICAgY29uc3QgbWV0YWRhdGEgPSBzZWxlY3Rpb24ubWV0YWRhdGE7XG4gICAgY29uc3QgY2xpZW50RW50cnkgPSB0aGlzLmFjcXVpcmVDbGllbnQoc2VsZWN0aW9uKTtcbiAgICB0cnkge1xuICAgICAgZm9yIGF3YWl0IChjb25zdCBldmVudCBvZiBjbGllbnRFbnRyeS5jbGllbnQucmVzcG9uc2VzKFxuICAgICAgICByZXF1ZXN0T3B0aW9ucyhyZXEpLFxuICAgICAgICByZXEuYWJvcnRTaWduYWwsXG4gICAgICApKSB7XG4gICAgICAgIGlmIChldmVudC50eXBlID09PSBcInRleHQtZGVsdGFcIikge1xuICAgICAgICAgIGZpcnN0RGVsdGFBdCA/Pz0gRGF0ZS5ub3coKTtcbiAgICAgICAgICB0ZXh0ICs9IGV2ZW50LnRleHQ7XG4gICAgICAgICAgb25EZWx0YT8uKGV2ZW50LnRleHQpO1xuICAgICAgICB9IGVsc2UgaWYgKGV2ZW50LnR5cGUgPT09IFwiaW1hZ2VcIikge1xuICAgICAgICAgIGltYWdlQXR0ZW1wdGVkID0gdHJ1ZTtcbiAgICAgICAgICBpbWFnZXMucHVzaCh7IGRhdGE6IGV2ZW50LmJhc2U2NCwgcmV2aXNlZFByb21wdDogZXZlbnQucmV2aXNlZFByb21wdCA/PyBudWxsIH0pO1xuICAgICAgICB9IGVsc2UgaWYgKGV2ZW50LnR5cGUgPT09IFwib3V0cHV0LWl0ZW1cIiAmJiBldmVudC5pdGVtLnR5cGUgPT09IFwiaW1hZ2VfZ2VuZXJhdGlvbl9jYWxsXCIpIHtcbiAgICAgICAgICBpbWFnZUF0dGVtcHRlZCA9IHRydWU7XG4gICAgICAgIH0gZWxzZSBpZiAoZXZlbnQudHlwZSA9PT0gXCJjb21wbGV0ZWRcIiAmJiBldmVudC51c2FnZSkge1xuICAgICAgICAgIHNlcnZpbmdNb2RlbCA9IGV2ZW50Lm1vZGVsID8/IHNlcnZpbmdNb2RlbDtcbiAgICAgICAgICB1c2FnZSA9IHtcbiAgICAgICAgICAgIHRvdGFsVG9rZW5zOiBldmVudC51c2FnZS50b3RhbFRva2VucyxcbiAgICAgICAgICAgIGlucHV0VG9rZW5zOiBldmVudC51c2FnZS5pbnB1dFRva2VucyxcbiAgICAgICAgICAgIG91dHB1dFRva2VuczogZXZlbnQudXNhZ2Uub3V0cHV0VG9rZW5zLFxuICAgICAgICAgICAgY2FjaGVkSW5wdXRUb2tlbnM6IGV2ZW50LnVzYWdlLmNhY2hlZElucHV0VG9rZW5zLFxuICAgICAgICAgICAgcmVhc29uaW5nT3V0cHV0VG9rZW5zOiBldmVudC51c2FnZS5yZWFzb25pbmdUb2tlbnMsXG4gICAgICAgICAgfTtcbiAgICAgICAgfSBlbHNlIGlmIChldmVudC50eXBlID09PSBcImNvbXBsZXRlZFwiKSB7XG4gICAgICAgICAgc2VydmluZ01vZGVsID0gZXZlbnQubW9kZWwgPz8gc2VydmluZ01vZGVsO1xuICAgICAgICB9IGVsc2UgaWYgKGV2ZW50LnR5cGUgPT09IFwiZXJyb3JcIikge1xuICAgICAgICAgIGlmIChyZXEuaW1hZ2VHZW5lcmF0aW9uKVxuICAgICAgICAgICAgdGhyb3cgbmV3IEltYWdlR2VuZXJhdGlvbkVycm9yKFwiaW5jb21wbGV0ZVwiLCBldmVudC5lcnJvci5tZXNzYWdlKTtcbiAgICAgICAgICB0aHJvdyBldmVudC5lcnJvcjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZmluYWxseSB7XG4gICAgICB0aGlzLnJlbGVhc2VDbGllbnQoY2xpZW50RW50cnkpO1xuICAgIH1cbiAgICBpZiAocmVxLmltYWdlR2VuZXJhdGlvbiAmJiBpbWFnZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgSW1hZ2VHZW5lcmF0aW9uRXJyb3IoXG4gICAgICAgIGltYWdlQXR0ZW1wdGVkID8gXCJpbmNvbXBsZXRlXCIgOiBcIm5vdF9jYWxsZWRcIixcbiAgICAgICAgaW1hZ2VBdHRlbXB0ZWRcbiAgICAgICAgICA/IFwiaW1hZ2UgZ2VuZXJhdGlvbiBkaWQgbm90IGNvbXBsZXRlXCJcbiAgICAgICAgICA6IFwibW9kZWwgZGlkIG5vdCBjYWxsIGltYWdlIGdlbmVyYXRpb25cIixcbiAgICAgICk7XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICB0ZXh0LFxuICAgICAgdG9rZW5OYW1lOiBtZXRhZGF0YS5uYW1lLFxuICAgICAgdXNhZ2UsXG4gICAgICBkdXJhdGlvbk1zOiBEYXRlLm5vdygpIC0gc3RhcnRlZEF0LFxuICAgICAgdHRmdE1zOiBmaXJzdERlbHRhQXQgPT09IHVuZGVmaW5lZCA/IG51bGwgOiBmaXJzdERlbHRhQXQgLSBzdGFydGVkQXQsXG4gICAgICBtb2RlbDogc2VydmluZ01vZGVsLFxuICAgICAgdGhyZWFkQ29vcmQ6IHsgd29ya2VySWQ6IHNlbGVjdGlvbi50b2tlbklkLCB0aHJlYWRJZDogcmVxLnByb21wdENhY2hlS2V5ID8/IFwiXCIsIGVwb2NoOiAtMSB9LFxuICAgICAgLi4uKGltYWdlcy5sZW5ndGggPyB7IGltYWdlcyB9IDoge30pLFxuICAgIH07XG4gIH1cblxuICAvKiog7IS464yA6rCAIOuwlOuAkCBjbGllbnQg64qUIOyCrOyaqSDspJHsnbgg7JqU7LKt7J20IOuBneuCnCDrkqTsl5Ag64ur64qU64ukLiAqL1xuICBwcml2YXRlIGFjcXVpcmVDbGllbnQoc2VsZWN0aW9uOiBUb2tlblNlbGVjdGlvbik6IENsaWVudEVudHJ5IHtcbiAgICBjb25zdCBtZXRhZGF0YSA9IHNlbGVjdGlvbi5tZXRhZGF0YTtcbiAgICBsZXQgZW50cnkgPSB0aGlzLmNsaWVudHMuZ2V0KHNlbGVjdGlvbi50b2tlbklkKTtcbiAgICBpZiAoZW50cnkgJiYgZW50cnkuZ2VuZXJhdGlvbiAhPT0gbWV0YWRhdGEuZ2VuZXJhdGlvbikge1xuICAgICAgdGhpcy5yZXRpcmVDbGllbnQoc2VsZWN0aW9uLnRva2VuSWQpO1xuICAgICAgZW50cnkgPSB1bmRlZmluZWQ7XG4gICAgfVxuICAgIGlmICghZW50cnkpIHtcbiAgICAgIGNvbnN0IGNsaWVudCA9IHRoaXMuY2xpZW50RmFjdG9yeShcbiAgICAgICAge1xuICAgICAgICAgIGNyZWRlbnRpYWxzOiB7XG4gICAgICAgICAgICBhY2Nlc3NUb2tlbjogbWV0YWRhdGEuY3JlZGVudGlhbHMuYWNjZXNzVG9rZW4sXG4gICAgICAgICAgICBhY2NvdW50SWQ6IG1ldGFkYXRhLmNyZWRlbnRpYWxzLmFjY291bnRJZCxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHRyYW5zcG9ydEtpbmQ6IHRoaXMudHJhbnNwb3J0S2luZCxcbiAgICAgICAgICBmZXRjaDogdGhpcy5mZXRjaEltcGwsXG4gICAgICAgICAgcmVmcmVzaENyZWRlbnRpYWxzOiBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCByZWZyZXNoZWQgPSBhd2FpdCBoYW5kbGVDaGF0Z3B0QXV0aFRva2Vuc1JlZnJlc2goc2VsZWN0aW9uLnRva2VuSWQpO1xuICAgICAgICAgICAgY29uc3QgY3VycmVudCA9IHRoaXMudG9rZW5NZXRhZGF0YS5nZXQoc2VsZWN0aW9uLnRva2VuSWQpO1xuICAgICAgICAgICAgaWYgKGN1cnJlbnQpXG4gICAgICAgICAgICAgIGN1cnJlbnQuY3JlZGVudGlhbHMgPSB7XG4gICAgICAgICAgICAgICAgLi4uY3VycmVudC5jcmVkZW50aWFscyxcbiAgICAgICAgICAgICAgICBhY2Nlc3NUb2tlbjogcmVmcmVzaGVkLmFjY2Vzc1Rva2VuLFxuICAgICAgICAgICAgICAgIGFjY291bnRJZDogcmVmcmVzaGVkLmNoYXRncHRBY2NvdW50SWQsXG4gICAgICAgICAgICAgIH07XG4gICAgICAgICAgICByZXR1cm4geyBhY2Nlc3NUb2tlbjogcmVmcmVzaGVkLmFjY2Vzc1Rva2VuLCBhY2NvdW50SWQ6IHJlZnJlc2hlZC5jaGF0Z3B0QWNjb3VudElkIH07XG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgICAgc2VsZWN0aW9uLnRva2VuSWQsXG4gICAgICApO1xuICAgICAgZW50cnkgPSB7IGdlbmVyYXRpb246IG1ldGFkYXRhLmdlbmVyYXRpb24sIGNsaWVudCwgaW5GbGlnaHQ6IDAsIHJldGlyZWQ6IGZhbHNlIH07XG4gICAgICB0aGlzLmNsaWVudHMuc2V0KHNlbGVjdGlvbi50b2tlbklkLCBlbnRyeSk7XG4gICAgfVxuICAgIGVudHJ5LmluRmxpZ2h0Kys7XG4gICAgcmV0dXJuIGVudHJ5O1xuICB9XG5cbiAgcHJpdmF0ZSByZWxlYXNlQ2xpZW50KGVudHJ5OiBDbGllbnRFbnRyeSk6IHZvaWQge1xuICAgIGVudHJ5LmluRmxpZ2h0ID0gTWF0aC5tYXgoMCwgZW50cnkuaW5GbGlnaHQgLSAxKTtcbiAgICBpZiAoZW50cnkucmV0aXJlZCAmJiBlbnRyeS5pbkZsaWdodCA9PT0gMCkge1xuICAgICAgdGhpcy5yZXRpcmVkQ2xpZW50cy5kZWxldGUoZW50cnkpO1xuICAgICAgZW50cnkuY2xpZW50LmNsb3NlPy4oKTtcbiAgICB9XG4gIH1cblxuICAvKiogbWFwIOyXkOyEnCDrlrzslrTrgrTqs6AsIOynhO2WiSDspJHsnbgg7JqU7LKt7J20IOyXhuydhCDrlYzrp4wg7KaJ7IucIOuLq+uKlOuLpC4gKi9cbiAgcHJpdmF0ZSByZXRpcmVDbGllbnQodG9rZW5JZDogbnVtYmVyKTogdm9pZCB7XG4gICAgY29uc3QgZW50cnkgPSB0aGlzLmNsaWVudHMuZ2V0KHRva2VuSWQpO1xuICAgIGlmICghZW50cnkpIHJldHVybjtcbiAgICB0aGlzLmNsaWVudHMuZGVsZXRlKHRva2VuSWQpO1xuICAgIGVudHJ5LnJldGlyZWQgPSB0cnVlO1xuICAgIGlmIChlbnRyeS5pbkZsaWdodCA9PT0gMCkgZW50cnkuY2xpZW50LmNsb3NlPy4oKTtcbiAgICBlbHNlIHRoaXMucmV0aXJlZENsaWVudHMuYWRkKGVudHJ5KTtcbiAgfVxuXG4gIC8qKlxuICAgKiDthqDtgbAg7ISg7YOdIOKAlCBxdW90YSBnYXRlIOulvCDthrXqs7ztlZwgYWN0aXZlIO2GoO2BsCDspJHsl5DshJwg6rOg66W464ukLiBjYWNoZSBhZmZpbml0eSDshKDtmLhcbiAgICog7Yag7YGw7J20IGVsaWdpYmxlIO2VmOuptCDqt7gg7YyQ7KCV66eM7Jy866GcIOymieyLnCDqsrDsoJXtlZjqs6Ao7KCE7LK0IHN3ZWVwIOyDneuetSwgd2VpZ2h0ZWQg7IOB7YOcXG4gICAqIOu5hOuzgOqyvSksIOyVhOuLiOuptCDrs5HroKwgcXVvdGEg7YyQ7KCVIO2bhCBzbW9vdGggd2VpZ2h0ZWQgcm91bmQtcm9iaW4uIOuPmeyLnOyEsSDsg4HtlZzsnbRcbiAgICog7JeG7Jy866+A66GcIFwi67mIIOyekOumrFwiIOqwnOuFkOuPhCDsl4bri6Qg4oCUIOyEoO2DnSDsponsi5wg7Iuk7ZaJ7J2064ukLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBzZWxlY3RUb2tlbihcbiAgICBwcmVmZXJyZWRUb2tlbklkOiBudW1iZXIgfCB1bmRlZmluZWQsXG4gICAgc2lnbmFsOiBBYm9ydFNpZ25hbCxcbiAgKTogUHJvbWlzZTxUb2tlblNlbGVjdGlvbj4ge1xuICAgIGlmIChwcmVmZXJyZWRUb2tlbklkICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGNvbnN0IHByZWZlcnJlZCA9IHRoaXMudG9rZW5NZXRhZGF0YS5nZXQocHJlZmVycmVkVG9rZW5JZCk7XG4gICAgICBpZiAocHJlZmVycmVkPy5hY3RpdmUgJiYgKGF3YWl0IHRoaXMuaXNRdW90YUVsaWdpYmxlKHByZWZlcnJlZFRva2VuSWQsIHByZWZlcnJlZCwgc2lnbmFsKSkpIHtcbiAgICAgICAgcmV0dXJuIHsgdG9rZW5JZDogcHJlZmVycmVkVG9rZW5JZCwgbWV0YWRhdGE6IHByZWZlcnJlZCB9O1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIO2GoO2BsOuzhCBxdW90YSDtjJDsoJXsnYAg7ISc66GcIOuPheumveydtOudvCDrs5HroKzroZwg4oCUIOyngeugrCDrjIDquLDripQg7L2c65OcIOy6kOyLnOyXkOyEnFxuICAgIC8vIO2GoO2BsCDsiJggw5cg7KGw7ZqMIOyngOyXsOunjO2BvCDsmpTssq0g7Iuc7J6R7J2EIOuKpuy2mOuLpC5cbiAgICBjb25zdCBjaGVja3MgPSBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgIFsuLi50aGlzLnRva2VuTWV0YWRhdGEuZW50cmllcygpXVxuICAgICAgICAuZmlsdGVyKChbLCB0b2tlbl0pID0+IHRva2VuLmFjdGl2ZSlcbiAgICAgICAgLm1hcChhc3luYyAoW2lkLCB0b2tlbl0pID0+ICh7XG4gICAgICAgICAgaWQsXG4gICAgICAgICAgdG9rZW4sXG4gICAgICAgICAgZWxpZ2libGU6IGF3YWl0IHRoaXMuaXNRdW90YUVsaWdpYmxlKGlkLCB0b2tlbiwgc2lnbmFsKSxcbiAgICAgICAgfSkpLFxuICAgICk7XG4gICAgY29uc3QgZWxpZ2libGUgPSBuZXcgU2V0KGNoZWNrcy5maWx0ZXIoKGMpID0+IGMuZWxpZ2libGUpLm1hcCgoYykgPT4gYy5pZCkpO1xuICAgIGlmIChlbGlnaWJsZS5zaXplID09PSAwKSB7XG4gICAgICBjb25zdCBvdmVyID0gY2hlY2tzXG4gICAgICAgIC5maWx0ZXIoXG4gICAgICAgICAgKGMpID0+XG4gICAgICAgICAgICAhYy5lbGlnaWJsZSAmJiBjLnRva2VuLnF1b3RhVGhyZXNob2xkICE9PSBudWxsICYmIGMudG9rZW4ucXVvdGFUaHJlc2hvbGQgIT09IHVuZGVmaW5lZCxcbiAgICAgICAgKVxuICAgICAgICAubWFwKChjKSA9PiAoeyBuYW1lOiBjLnRva2VuLm5hbWUsIHRocmVzaG9sZDogYy50b2tlbi5xdW90YVRocmVzaG9sZCBhcyBudW1iZXIgfSkpO1xuICAgICAgaWYgKG92ZXIubGVuZ3RoKSB7XG4gICAgICAgIGxvZ2dlci53YXJuKFwicXVvdGFfdGhyZXNob2xkIGdhdGU6IGFsbF9leGNlZWRlZFwiLCB7XG4gICAgICAgICAgcHJvdmlkZXI6IFwib3BlbmFpXCIsXG4gICAgICAgICAgb3ZlclRocmVzaG9sZFRva2Vuczogb3ZlcixcbiAgICAgICAgfSk7XG4gICAgICAgIHRocm93IG5ldyBRdW90YVRocmVzaG9sZEV4Y2VlZGVkRXJyb3IocXVvdGFNZXNzYWdlKG92ZXIpKTtcbiAgICAgIH1cbiAgICAgIHRocm93IG5ldyBFcnJvcihcIk5PX09QRU5BSV9XT1JLRVJTXCIpO1xuICAgIH1cbiAgICBjb25zdCBzZWxlY3RlZCA9IHRoaXMuc2VsZWN0b3Iuc2VsZWN0KGVsaWdpYmxlKTtcbiAgICBjb25zdCBtZXRhZGF0YSA9IHNlbGVjdGVkICE9PSBudWxsID8gdGhpcy50b2tlbk1ldGFkYXRhLmdldChzZWxlY3RlZCkgOiB1bmRlZmluZWQ7XG4gICAgaWYgKHNlbGVjdGVkID09PSBudWxsIHx8ICFtZXRhZGF0YSkgdGhyb3cgbmV3IEVycm9yKFwiTk9fT1BFTkFJX1dPUktFUlNcIik7XG4gICAgcmV0dXJuIHsgdG9rZW5JZDogc2VsZWN0ZWQsIG1ldGFkYXRhIH07XG4gIH1cblxuICBwcml2YXRlIHNldFRva2VuKFxuICAgIGlkOiBudW1iZXIsXG4gICAgbmFtZTogc3RyaW5nLFxuICAgIGNyZWRlbnRpYWxzOiBPcGVuQUlDcmVkZW50aWFscyxcbiAgICBxdW90YVRocmVzaG9sZDogbnVtYmVyIHwgbnVsbCB8IHVuZGVmaW5lZCxcbiAgICB3ZWlnaHQ6IG51bWJlcixcbiAgICBhY3RpdmU6IGJvb2xlYW4sXG4gICk6IHZvaWQge1xuICAgIGNvbnN0IG9sZCA9IHRoaXMudG9rZW5NZXRhZGF0YS5nZXQoaWQpO1xuICAgIGlmIChvbGQpIHtcbiAgICAgIE9iamVjdC5hc3NpZ24ob2xkLCB7XG4gICAgICAgIG5hbWUsXG4gICAgICAgIGNyZWRlbnRpYWxzLFxuICAgICAgICBxdW90YVRocmVzaG9sZCxcbiAgICAgICAgd2VpZ2h0LFxuICAgICAgICBhY3RpdmUsXG4gICAgICAgIGdlbmVyYXRpb246IG9sZC5nZW5lcmF0aW9uICsgMSxcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnRva2VuTWV0YWRhdGEuc2V0KGlkLCB7XG4gICAgICAgIG5hbWUsXG4gICAgICAgIGNyZWRlbnRpYWxzLFxuICAgICAgICBxdW90YVRocmVzaG9sZCxcbiAgICAgICAgd2VpZ2h0LFxuICAgICAgICBhY3RpdmUsXG4gICAgICAgIGdlbmVyYXRpb246IDEsXG4gICAgICB9KTtcbiAgICB9XG4gICAgdGhpcy5zZWxlY3Rvci5zZXRUb2tlbihpZCwgd2VpZ2h0KTtcbiAgICB0aGlzLmludmFsaWRhdGVSYXRlTGltaXRzQ2FjaGUoaWQpO1xuICAgIHRoaXMucXVvdGFCbG9ja2VkLmRlbGV0ZShpZCk7XG4gIH1cblxuICBhc3luYyBnZXRSYXRlTGltaXRzQnlUb2tlbklkKFxuICAgIHRva2VuSWQ6IG51bWJlcixcbiAgICBzaWduYWw/OiBBYm9ydFNpZ25hbCxcbiAgKTogUHJvbWlzZTxPcGVuQUlSYXRlTGltaXRzV2l0aE1ldGE+IHtcbiAgICBjb25zdCB0b2tlbiA9IHRoaXMudG9rZW5NZXRhZGF0YS5nZXQodG9rZW5JZCk7XG4gICAgaWYgKCF0b2tlbikgdGhyb3cgbmV3IEVycm9yKGBvcGVuYWkgdG9rZW4gJHt0b2tlbklkfSBub3QgZm91bmRgKTtcbiAgICBjb25zdCBjYWNoZWQgPSB0aGlzLnJhdGVMaW1pdHNDYWNoZS5nZXQodG9rZW5JZCk7XG4gICAgaWYgKFxuICAgICAgY2FjaGVkICYmXG4gICAgICBjYWNoZWQuZ2VuZXJhdGlvbiA9PT0gdG9rZW4uZ2VuZXJhdGlvbiAmJlxuICAgICAgRGF0ZS5ub3coKSAtIGNhY2hlZC5jYWNoZWRBdCA8IE9wZW5BSURpc3BhdGNoZXIuUkFURV9MSU1JVFNfQ0FDSEVfVFRMXG4gICAgKVxuICAgICAgcmV0dXJuIGNhY2hlZDtcblxuICAgIC8vIHNpbmdsZS1mbGlnaHQ6IOuPmeyLnOyEsSDsg4HtlZzsnbQg7JeG7Ja07KeEIOuSpOuhnCBUVEwg66eM66OMIOyInOqwhCDrj5nsi5wg7JqU7LKtIOyImOunjO2BvCDqsJnsnYBcbiAgICAvLyDsobDtmozqsIAg66qw66a0IOyImCDsnojri6Qg4oCUIOynhO2WiSDspJHsnbggZmV0Y2gg66W8IOqzteycoO2VnOuLpC4g7LWc7LSIIO2YuOy2nOyekOydmCBhYm9ydCDroZxcbiAgICAvLyDqs7XsnKAg7KGw7ZqM6rCAIOyLpO2MqO2VtOuPhCDshozruYTsspgoaXNRdW90YUVsaWdpYmxlKeqwgCBmYWlsLW9wZW4g7Jy866GcIOyymOumrO2VnOuLpC5cbiAgICBjb25zdCBwZW5kaW5nID0gdGhpcy5wZW5kaW5nUmF0ZUxpbWl0cy5nZXQodG9rZW5JZCk7XG4gICAgaWYgKHBlbmRpbmcpIHJldHVybiBwZW5kaW5nO1xuICAgIGNvbnN0IGZldGNoUHJvbWlzZSA9IChhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCByZWFkT3BlbkFJUXVvdGFVc2FnZSh7XG4gICAgICAgIGNyZWRlbnRpYWxzOiB0b2tlbi5jcmVkZW50aWFscyxcbiAgICAgICAgZmV0Y2g6IHRoaXMuZmV0Y2hJbXBsLFxuICAgICAgICAuLi4oc2lnbmFsID8geyBzaWduYWwgfSA6IHt9KSxcbiAgICAgIH0pO1xuICAgICAgaWYgKHJlc3VsdC5raW5kID09PSBcImxvb2t1cF9mYWlsZWRcIikgdGhyb3cgbmV3IEVycm9yKHJlc3VsdC5yZWFzb24pO1xuICAgICAgaWYgKCFyZXN1bHQucmF3KSB0aHJvdyBuZXcgRXJyb3IoXCJPcGVuQUkgcXVvdGEgcmVzcG9uc2UgbWlzc2luZyByYXcgcmF0ZSBsaW1pdHNcIik7XG4gICAgICBjb25zdCBlbnRyeSA9IHsgZGF0YTogcmVzdWx0LnJhdywgY2FjaGVkQXQ6IERhdGUubm93KCksIGdlbmVyYXRpb246IHRva2VuLmdlbmVyYXRpb24gfTtcbiAgICAgIGlmICh0aGlzLnRva2VuTWV0YWRhdGEuZ2V0KHRva2VuSWQpID09PSB0b2tlbikgdGhpcy5yYXRlTGltaXRzQ2FjaGUuc2V0KHRva2VuSWQsIGVudHJ5KTtcbiAgICAgIHJldHVybiBlbnRyeTtcbiAgICB9KSgpLmZpbmFsbHkoKCkgPT4gdGhpcy5wZW5kaW5nUmF0ZUxpbWl0cy5kZWxldGUodG9rZW5JZCkpO1xuICAgIHRoaXMucGVuZGluZ1JhdGVMaW1pdHMuc2V0KHRva2VuSWQsIGZldGNoUHJvbWlzZSk7XG4gICAgcmV0dXJuIGZldGNoUHJvbWlzZTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgaXNRdW90YUVsaWdpYmxlKFxuICAgIGlkOiBudW1iZXIsXG4gICAgdG9rZW46IFRva2VuTWV0YWRhdGEsXG4gICAgc2lnbmFsPzogQWJvcnRTaWduYWwsXG4gICk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIGlmICh0b2tlbi5xdW90YVRocmVzaG9sZCA9PT0gbnVsbCB8fCB0b2tlbi5xdW90YVRocmVzaG9sZCA9PT0gdW5kZWZpbmVkKSByZXR1cm4gdHJ1ZTtcbiAgICBjb25zdCBnZW5lcmF0aW9uID0gdG9rZW4uZ2VuZXJhdGlvbjtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCByZWFkT3BlbkFJUXVvdGFVc2FnZShhc3luYyAoKSA9PiB0aGlzLmdldFJhdGVMaW1pdHNCeVRva2VuSWQoaWQsIHNpZ25hbCkpO1xuICAgIGlmICh0aGlzLnRva2VuTWV0YWRhdGEuZ2V0KGlkKSAhPT0gdG9rZW4gfHwgdG9rZW4uZ2VuZXJhdGlvbiAhPT0gZ2VuZXJhdGlvbikgcmV0dXJuIGZhbHNlO1xuICAgIGlmIChyZXN1bHQua2luZCA9PT0gXCJsb29rdXBfZmFpbGVkXCIpIHtcbiAgICAgIHRoaXMucXVvdGFCbG9ja2VkLmRlbGV0ZShpZCk7XG4gICAgICBsb2dnZXIud2FybihcInF1b3RhX3RocmVzaG9sZCBnYXRlOiBsb29rdXBfZmFpbF9vcGVuXCIsIHtcbiAgICAgICAgdG9rZW5JZDogaWQsXG4gICAgICAgIHRva2VuTmFtZTogdG9rZW4ubmFtZSxcbiAgICAgICAgbG9va3VwUmVhc29uOiByZXN1bHQucmVhc29uLFxuICAgICAgfSk7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgaWYgKHJlc3VsdC51dGlsaXphdGlvblBjdCA+PSB0b2tlbi5xdW90YVRocmVzaG9sZCkge1xuICAgICAgaWYgKCF0aGlzLnF1b3RhQmxvY2tlZC5oYXMoaWQpKVxuICAgICAgICBsb2dnZXIuaW5mbyhcbiAgICAgICAgICBgcXVvdGFfdGhyZXNob2xkIGdhdGU6IG92ZXJfdGhyZXNob2xkICR7dG9rZW4ubmFtZX1bJHtpZH1dICgke3Jlc3VsdC51dGlsaXphdGlvblBjdH0lID49ICR7dG9rZW4ucXVvdGFUaHJlc2hvbGR9JSlgLFxuICAgICAgICApO1xuICAgICAgdGhpcy5xdW90YUJsb2NrZWQuYWRkKGlkKTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgaWYgKHRoaXMucXVvdGFCbG9ja2VkLmRlbGV0ZShpZCkpXG4gICAgICBsb2dnZXIuaW5mbyhcbiAgICAgICAgYHF1b3RhX3RocmVzaG9sZCBnYXRlOiByZWNvdmVyZWQgJHt0b2tlbi5uYW1lfVske2lkfV0gKCR7cmVzdWx0LnV0aWxpemF0aW9uUGN0fSUgPCAke3Rva2VuLnF1b3RhVGhyZXNob2xkfSUpYCxcbiAgICAgICk7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBwcml2YXRlIGludmFsaWRhdGVSYXRlTGltaXRzQ2FjaGUoaWQ6IG51bWJlcik6IHZvaWQge1xuICAgIHRoaXMucmF0ZUxpbWl0c0NhY2hlLmRlbGV0ZShpZCk7XG4gIH1cblxuICBnZXQgdG9rZW5Db3VudCgpOiBudW1iZXIge1xuICAgIHJldHVybiBbLi4udGhpcy50b2tlbk1ldGFkYXRhLnZhbHVlcygpXS5maWx0ZXIoKHQpID0+IHQuYWN0aXZlKS5sZW5ndGg7XG4gIH1cbiAgZ2V0IGluRmxpZ2h0KCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuaW5GbGlnaHRDb3VudDtcbiAgfVxuXG4gIC8qKlxuICAgKiDthqDtgbDrs4Qg7L+87YSwIOyKpOuDheyDtyDigJQg7Iug7ISg7ZWcKHJhdGUgbGltaXRzIFRUTCDrgrQpIOy6kOyLnOunjCDsnb3qs6Ag7KCI64yAIGZldGNoIO2VmOyngCDslYrripTri6QuXG4gICAqIG1vbml0IHZpdGFscyDripQg66Gc6re4IO2PtOungeyXkCDtjrjsirntlZjripQg6rCS7J206528IOyXrOq4sOyEnCDrhKTtirjsm4ztgazrpbwg7YOA66m0IOyViCDrkJzri6QuXG4gICAqIHRocmVzaG9sZCDrr7jshKTsoJUg7Yag7YGw7J2AIOy/vO2EsCDtjJDsoJXsnYQg64+M7KeAIOyViuyVhCB1c2VkUGVyY2VudCDqsIAgbnVsbCDroZwg64Ko7J2EIOyImCDsnojri6QuXG4gICAqL1xuICBnZXQgcXVvdGFCeVRva2VuKCk6IEFycmF5PHtcbiAgICBuYW1lOiBzdHJpbmc7XG4gICAgdXNlZFBlcmNlbnQ6IG51bWJlciB8IG51bGw7XG4gICAgdGhyZXNob2xkOiBudW1iZXIgfCBudWxsO1xuICAgIGJsb2NrZWQ6IGJvb2xlYW47XG4gICAgcmVzZXRzQXQ6IG51bWJlciB8IG51bGw7XG4gIH0+IHtcbiAgICBjb25zdCBub3cgPSBEYXRlLm5vdygpO1xuICAgIHJldHVybiBbLi4udGhpcy50b2tlbk1ldGFkYXRhLmVudHJpZXMoKV1cbiAgICAgIC5tYXAoKFtpZCwgdF0pID0+IHtcbiAgICAgICAgY29uc3QgY2FjaGVkID0gdGhpcy5yYXRlTGltaXRzQ2FjaGUuZ2V0KGlkKTtcbiAgICAgICAgY29uc3QgZnJlc2ggPVxuICAgICAgICAgIGNhY2hlZCAhPT0gdW5kZWZpbmVkICYmXG4gICAgICAgICAgY2FjaGVkLmdlbmVyYXRpb24gPT09IHQuZ2VuZXJhdGlvbiAmJlxuICAgICAgICAgIG5vdyAtIGNhY2hlZC5jYWNoZWRBdCA8IE9wZW5BSURpc3BhdGNoZXIuUkFURV9MSU1JVFNfQ0FDSEVfVFRMO1xuICAgICAgICBjb25zdCBwcmltYXJ5ID0gZnJlc2ggPyBjYWNoZWQuZGF0YS5yYXRlTGltaXRzPy5wcmltYXJ5IDogdW5kZWZpbmVkO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIG5hbWU6IHQubmFtZSxcbiAgICAgICAgICB1c2VkUGVyY2VudDogcHJpbWFyeT8udXNlZFBlcmNlbnQgPz8gbnVsbCxcbiAgICAgICAgICB0aHJlc2hvbGQ6IHQucXVvdGFUaHJlc2hvbGQgPz8gbnVsbCxcbiAgICAgICAgICBibG9ja2VkOiB0aGlzLnF1b3RhQmxvY2tlZC5oYXMoaWQpLFxuICAgICAgICAgIC8vIHdoYW0g7J2YIHJlc2V0c0F0IOydgCB1bml4IOy0iCDri6jsnITri6QocWdyaWQuZnJhbWUgdW5peFNlY29uZHNUb0lzbyDsmYAg64+Z7J28IOq3nOyVvSkuXG4gICAgICAgICAgLy8g7IaM67mE7LKY6rCAIOuLqOychOulvCDstpTsuKHtlZjsp4Ag7JWK64+E66GdIOyXrOq4sOyEnCBtcyBlcG9jaCDsnLzroZwg7KCV6rec7ZmU7ZWc64ukLlxuICAgICAgICAgIHJlc2V0c0F0OlxuICAgICAgICAgICAgcHJpbWFyeT8ucmVzZXRzQXQgIT09IG51bGwgJiYgcHJpbWFyeT8ucmVzZXRzQXQgIT09IHVuZGVmaW5lZFxuICAgICAgICAgICAgICA/IHByaW1hcnkucmVzZXRzQXQgKiAxMDAwXG4gICAgICAgICAgICAgIDogbnVsbCxcbiAgICAgICAgfTtcbiAgICAgIH0pXG4gICAgICAudG9Tb3J0ZWQoKGEsIGIpID0+IGEubmFtZS5sb2NhbGVDb21wYXJlKGIubmFtZSkpO1xuICB9XG59XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7OztBQXVCQSxNQUFNLFNBQVMsVUFBVSxDQUFDLFNBQVMsbUJBQW1CLENBQUM7QUFHdkQsTUFBTSw2QkFBNkI7QUFJ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
|