sonamu 0.10.12 → 0.10.13
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/dist/ai/agents/agent.d.ts +1 -1
- package/dist/ai/agents/agent.d.ts.map +1 -1
- package/dist/ai/agents/agent.js +5 -6
- package/dist/ai/agents/types.d.ts +1 -1
- package/dist/ai/agents/types.d.ts.map +1 -1
- package/dist/ai/providers/rtzr/api.js +18 -18
- package/dist/ai/providers/rtzr/error.d.ts.map +1 -1
- package/dist/ai/providers/rtzr/error.js +17 -15
- package/dist/ai/providers/rtzr/model.d.ts.map +1 -1
- package/dist/ai/providers/rtzr/model.js +3 -2
- package/dist/ai/providers/rtzr/options.d.ts.map +1 -1
- package/dist/ai/providers/rtzr/options.js +16 -16
- package/dist/ai/providers/rtzr/provider.d.ts.map +1 -1
- package/dist/ai/providers/rtzr/provider.js +9 -9
- package/dist/ai/providers/rtzr/utils.d.ts.map +1 -1
- package/dist/ai/providers/rtzr/utils.js +1 -1
- package/dist/api/caster.d.ts.map +1 -1
- package/dist/api/caster.js +17 -17
- package/dist/api/code-converters.d.ts +4 -2
- package/dist/api/code-converters.d.ts.map +1 -1
- package/dist/api/code-converters.js +100 -19
- package/dist/api/config.d.ts +16 -1
- package/dist/api/config.d.ts.map +1 -1
- package/dist/api/config.js +28 -21
- package/dist/api/context.d.ts +2 -2
- package/dist/api/context.d.ts.map +1 -1
- package/dist/api/context.js +1 -1
- package/dist/api/decorators.d.ts.map +1 -1
- package/dist/api/decorators.js +18 -11
- package/dist/api/http-validator.d.ts +36 -0
- package/dist/api/http-validator.d.ts.map +1 -0
- package/dist/api/http-validator.js +72 -0
- package/dist/api/index.js +6 -4
- package/dist/api/sonamu.d.ts +59 -20
- package/dist/api/sonamu.d.ts.map +1 -1
- package/dist/api/sonamu.js +250 -106
- package/dist/api/websocket-helpers.d.ts +7 -5
- package/dist/api/websocket-helpers.d.ts.map +1 -1
- package/dist/api/websocket-helpers.js +6 -6
- package/dist/auth/audit-log/builders.d.ts.map +1 -1
- package/dist/auth/audit-log/builders.js +1 -1
- package/dist/auth/audit-log/client-ip.d.ts +1 -1
- package/dist/auth/audit-log/client-ip.d.ts.map +1 -1
- package/dist/auth/audit-log/client-ip.js +4 -2
- package/dist/auth/audit-log/events.d.ts +5 -1
- package/dist/auth/audit-log/events.d.ts.map +1 -1
- package/dist/auth/audit-log/events.js +1 -1
- package/dist/auth/audit-log/plugin.d.ts +0 -8
- package/dist/auth/audit-log/plugin.d.ts.map +1 -1
- package/dist/auth/audit-log/plugin.js +48 -52
- package/dist/auth/audit-log-ingestor.d.ts.map +1 -1
- package/dist/auth/audit-log-ingestor.js +16 -12
- package/dist/auth/auth-generator.d.ts.map +1 -1
- package/dist/auth/auth-generator.js +1 -1
- package/dist/auth/better-auth-request.d.ts.map +1 -1
- package/dist/auth/better-auth-request.js +6 -5
- package/dist/auth/knex-adapter.js +1 -1
- package/dist/auth/plugins/entity-definitions/index.d.ts +13 -1
- package/dist/auth/plugins/entity-definitions/index.d.ts.map +1 -1
- package/dist/auth/plugins/entity-definitions/index.js +1 -1
- package/dist/auth/plugins/wrappers/admin.d.ts +1 -1
- package/dist/bin/build-config.d.ts +25 -0
- package/dist/bin/build-config.d.ts.map +1 -1
- package/dist/bin/build-config.js +105 -2
- package/dist/bin/cli.js +131 -27
- package/dist/bin/compiler-policy.d.ts +3 -0
- package/dist/bin/compiler-policy.d.ts.map +1 -0
- package/dist/bin/compiler-policy.js +24 -0
- package/dist/bin/fixture.d.ts.map +1 -1
- package/dist/bin/fixture.js +5 -3
- package/dist/bin/test-command.d.ts +22 -1
- package/dist/bin/test-command.d.ts.map +1 -1
- package/dist/bin/test-command.js +18 -10
- package/dist/bin/ts-loader-registration.d.ts +7 -1
- package/dist/bin/ts-loader-registration.d.ts.map +1 -1
- package/dist/bin/ts-loader-registration.js +13 -4
- package/dist/cache/decorator.d.ts.map +1 -1
- package/dist/cache/decorator.js +11 -4
- package/dist/compress/compress.d.ts.map +1 -1
- package/dist/compress/compress.js +1 -1
- package/dist/cone/cone-generator.d.ts +14 -1
- package/dist/cone/cone-generator.d.ts.map +1 -1
- package/dist/cone/cone-generator.js +13 -9
- package/dist/database/_batch_update.js +1 -1
- package/dist/database/base-model.d.ts +22 -10
- package/dist/database/base-model.d.ts.map +1 -1
- package/dist/database/base-model.js +26 -16
- package/dist/database/base-model.types.d.ts +15 -3
- package/dist/database/base-model.types.d.ts.map +1 -1
- package/dist/database/db.d.ts +12 -2
- package/dist/database/db.d.ts.map +1 -1
- package/dist/database/db.js +10 -7
- package/dist/database/knex.d.ts.map +1 -1
- package/dist/database/knex.js +17 -14
- package/dist/database/puri.d.ts +11 -9
- package/dist/database/puri.d.ts.map +1 -1
- package/dist/database/puri.js +93 -79
- package/dist/database/puri.types.d.ts +21 -21
- package/dist/database/puri.types.d.ts.map +1 -1
- package/dist/database/puri.types.js +1 -1
- package/dist/database/upsert-builder.d.ts +12 -10
- package/dist/database/upsert-builder.d.ts.map +1 -1
- package/dist/database/upsert-builder.js +20 -12
- package/dist/dict/sd.d.ts.map +1 -1
- package/dist/dict/sd.js +1 -1
- package/dist/dict/sonamu-dictionary.d.ts.map +1 -1
- package/dist/dict/sonamu-dictionary.js +1 -1
- package/dist/dict/utils.d.ts.map +1 -1
- package/dist/dict/utils.js +7 -2
- package/dist/entity/entity-manager.d.ts +13 -4
- package/dist/entity/entity-manager.d.ts.map +1 -1
- package/dist/entity/entity-manager.js +19 -11
- package/dist/entity/entity-template-cone.d.ts +73 -5
- package/dist/entity/entity-template-cone.d.ts.map +1 -1
- package/dist/entity/entity-template-cone.js +4 -2
- package/dist/entity/entity.d.ts +6 -2
- package/dist/entity/entity.d.ts.map +1 -1
- package/dist/entity/entity.js +30 -28
- package/dist/env.d.ts +3 -1
- package/dist/env.d.ts.map +1 -1
- package/dist/env.js +1 -1
- package/dist/exceptions/error-handler.d.ts.map +1 -1
- package/dist/exceptions/error-handler.js +7 -2
- package/dist/exceptions/so-exceptions.d.ts +24 -20
- package/dist/exceptions/so-exceptions.d.ts.map +1 -1
- package/dist/exceptions/so-exceptions.js +4 -2
- package/dist/filter/utils.d.ts +7 -2
- package/dist/filter/utils.d.ts.map +1 -1
- package/dist/filter/utils.js +8 -6
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -6
- package/dist/logger/configure.d.ts.map +1 -1
- package/dist/logger/configure.js +10 -10
- package/dist/migration/code-generation.d.ts.map +1 -1
- package/dist/migration/code-generation.js +50 -46
- package/dist/migration/index-where-predicate.d.ts.map +1 -1
- package/dist/migration/index-where-predicate.js +22 -8
- package/dist/migration/migration-set.d.ts.map +1 -1
- package/dist/migration/migration-set.js +1 -1
- package/dist/migration/migrator.d.ts +3 -2
- package/dist/migration/migrator.d.ts.map +1 -1
- package/dist/migration/migrator.js +27 -21
- package/dist/migration/postgresql-schema-reader.d.ts.map +1 -1
- package/dist/migration/postgresql-schema-reader.js +51 -36
- package/dist/migration/slack-confirm.d.ts.map +1 -1
- package/dist/migration/slack-confirm.js +1 -1
- package/dist/naite/naite-reporter.js +2 -2
- package/dist/naite/naite.d.ts +74 -15
- package/dist/naite/naite.d.ts.map +1 -1
- package/dist/naite/naite.js +5 -19
- package/dist/runtime-type.d.ts +6 -0
- package/dist/runtime-type.d.ts.map +1 -0
- package/dist/runtime-type.js +26 -0
- package/dist/ssr/hmr-opt-out.d.ts +26 -0
- package/dist/ssr/hmr-opt-out.d.ts.map +1 -0
- package/dist/ssr/hmr-opt-out.js +59 -0
- package/dist/ssr/renderer.d.ts.map +1 -1
- package/dist/ssr/renderer.js +4 -1
- package/dist/storage/base-file.js +14 -14
- package/dist/storage/buffered-file.d.ts +2 -2
- package/dist/storage/buffered-file.d.ts.map +1 -1
- package/dist/storage/buffered-file.js +12 -12
- package/dist/storage/s3-driver.d.ts.map +1 -1
- package/dist/storage/s3-driver.js +1 -1
- package/dist/storage/uploaded-file.d.ts +2 -2
- package/dist/storage/uploaded-file.d.ts.map +1 -1
- package/dist/storage/uploaded-file.js +8 -8
- package/dist/stream/sse.js +11 -11
- package/dist/stream/ws-core.d.ts +1 -1
- package/dist/stream/ws-core.d.ts.map +1 -1
- package/dist/stream/ws-delivery.d.ts +1 -1
- package/dist/stream/ws-delivery.d.ts.map +1 -1
- package/dist/stream/ws-delivery.js +6 -4
- package/dist/stream/ws-local-connection-store.d.ts.map +1 -1
- package/dist/stream/ws-local-connection-store.js +4 -2
- package/dist/stream/ws-presence-store.js +1 -1
- package/dist/stream/ws-registry.d.ts +4 -4
- package/dist/stream/ws-registry.d.ts.map +1 -1
- package/dist/stream/ws-registry.js +4 -2
- package/dist/stream/ws-telemetry.d.ts +16 -12
- package/dist/stream/ws-telemetry.d.ts.map +1 -1
- package/dist/stream/ws-telemetry.js +22 -18
- package/dist/stream/ws.d.ts +18 -12
- package/dist/stream/ws.d.ts.map +1 -1
- package/dist/stream/ws.js +26 -22
- package/dist/syncer/api-parser.js +1 -1
- package/dist/syncer/checksum.d.ts.map +1 -1
- package/dist/syncer/checksum.js +7 -8
- package/dist/syncer/code-generator.d.ts.map +1 -1
- package/dist/syncer/code-generator.js +13 -14
- package/dist/syncer/entity-operations.d.ts.map +1 -1
- package/dist/syncer/entity-operations.js +5 -6
- package/dist/syncer/file-copy.d.ts +5 -0
- package/dist/syncer/file-copy.d.ts.map +1 -0
- package/dist/syncer/file-copy.js +36 -0
- package/dist/syncer/file-patterns.d.ts +1 -0
- package/dist/syncer/file-patterns.d.ts.map +1 -1
- package/dist/syncer/file-patterns.js +5 -2
- package/dist/syncer/file-tracking.d.ts.map +1 -1
- package/dist/syncer/file-tracking.js +5 -4
- package/dist/syncer/filesystem-dependencies.d.ts +15 -0
- package/dist/syncer/filesystem-dependencies.d.ts.map +1 -0
- package/dist/syncer/filesystem-dependencies.js +53 -0
- package/dist/syncer/module-loader.d.ts +1 -1
- package/dist/syncer/module-loader.d.ts.map +1 -1
- package/dist/syncer/module-loader.js +6 -4
- package/dist/syncer/syncer-actions.d.ts +4 -0
- package/dist/syncer/syncer-actions.d.ts.map +1 -1
- package/dist/syncer/syncer-actions.js +34 -17
- package/dist/syncer/syncer.d.ts +17 -6
- package/dist/syncer/syncer.d.ts.map +1 -1
- package/dist/syncer/syncer.js +71 -29
- package/dist/syncer/watcher.d.ts.map +1 -1
- package/dist/syncer/watcher.js +3 -3
- package/dist/tasks/decorator.d.ts +6 -6
- package/dist/tasks/decorator.d.ts.map +1 -1
- package/dist/tasks/decorator.js +4 -4
- package/dist/tasks/step-wrapper.d.ts +6 -4
- package/dist/tasks/step-wrapper.d.ts.map +1 -1
- package/dist/tasks/step-wrapper.js +5 -5
- package/dist/tasks/workflow-manager.d.ts.map +1 -1
- package/dist/tasks/workflow-manager.js +13 -7
- package/dist/template/entity-converter.d.ts +1 -1
- package/dist/template/entity-converter.d.ts.map +1 -1
- package/dist/template/entity-converter.js +2 -2
- package/dist/template/helpers.d.ts +8 -6
- package/dist/template/helpers.d.ts.map +1 -1
- package/dist/template/helpers.js +1 -1
- package/dist/template/implementations/generated.template.d.ts.map +1 -1
- package/dist/template/implementations/generated.template.js +4 -4
- package/dist/template/implementations/generated_http.template.d.ts +7 -4
- package/dist/template/implementations/generated_http.template.d.ts.map +1 -1
- package/dist/template/implementations/generated_http.template.js +21 -21
- package/dist/template/implementations/generated_sso.template.d.ts.map +1 -1
- package/dist/template/implementations/generated_sso.template.js +6 -3
- package/dist/template/implementations/http_validators.template.d.ts +18 -0
- package/dist/template/implementations/http_validators.template.d.ts.map +1 -0
- package/dist/template/implementations/http_validators.template.js +127 -0
- package/dist/template/implementations/model.template.d.ts.map +1 -1
- package/dist/template/implementations/model.template.js +1 -1
- package/dist/template/implementations/queries.template.js +1 -1
- package/dist/template/implementations/sd.template.d.ts.map +1 -1
- package/dist/template/implementations/sd.template.js +79 -39
- package/dist/template/implementations/services.template.d.ts.map +1 -1
- package/dist/template/implementations/services.template.js +6 -4
- package/dist/template/implementations/view_form.template.d.ts +6 -1
- package/dist/template/implementations/view_form.template.d.ts.map +1 -1
- package/dist/template/implementations/view_form.template.js +23 -15
- package/dist/template/implementations/view_list.template.d.ts.map +1 -1
- package/dist/template/implementations/view_list.template.js +11 -6
- package/dist/template/template-manager.d.ts.map +1 -1
- package/dist/template/template-manager.js +9 -7
- package/dist/template/template-types.d.ts +12 -5
- package/dist/template/template-types.d.ts.map +1 -1
- package/dist/template/template-types.js +1 -1
- package/dist/template/template.d.ts +2 -2
- package/dist/template/template.d.ts.map +1 -1
- package/dist/template/template.js +6 -4
- package/dist/template/zod-converter.d.ts +0 -19
- package/dist/template/zod-converter.d.ts.map +1 -1
- package/dist/template/zod-converter.js +100 -84
- package/dist/testing/_relation-graph.d.ts.map +1 -1
- package/dist/testing/_relation-graph.js +2 -1
- package/dist/testing/bootstrap.d.ts.map +1 -1
- package/dist/testing/bootstrap.js +9 -6
- package/dist/testing/data-explorer.d.ts +32 -7
- package/dist/testing/data-explorer.d.ts.map +1 -1
- package/dist/testing/data-explorer.js +77 -31
- package/dist/testing/dev-test-routes.d.ts +8 -1
- package/dist/testing/dev-test-routes.d.ts.map +1 -1
- package/dist/testing/dev-test-routes.js +125 -108
- package/dist/testing/dev-vitest-manager.d.ts +54 -8
- package/dist/testing/dev-vitest-manager.d.ts.map +1 -1
- package/dist/testing/dev-vitest-manager.js +24 -9
- package/dist/testing/faker-mappings.d.ts +412 -1
- package/dist/testing/faker-mappings.d.ts.map +1 -1
- package/dist/testing/faker-mappings.js +1 -1
- package/dist/testing/filesystem.d.ts +2 -0
- package/dist/testing/filesystem.d.ts.map +1 -0
- package/dist/testing/filesystem.js +7 -0
- package/dist/testing/fixture-generator.d.ts +25 -8
- package/dist/testing/fixture-generator.d.ts.map +1 -1
- package/dist/testing/fixture-generator.js +132 -73
- package/dist/testing/fixture-loader.d.ts +3 -1
- package/dist/testing/fixture-loader.d.ts.map +1 -1
- package/dist/testing/fixture-loader.js +1 -20
- package/dist/testing/fixture-manager.d.ts +8 -7
- package/dist/testing/fixture-manager.d.ts.map +1 -1
- package/dist/testing/fixture-manager.js +91 -59
- package/dist/testing/global-setup.d.ts.map +1 -1
- package/dist/testing/global-setup.js +5 -2
- package/dist/testing/index.d.ts +2 -0
- package/dist/testing/index.d.ts.map +1 -1
- package/dist/testing/index.js +6 -3
- package/dist/types/types.d.ts +101 -99
- package/dist/types/types.d.ts.map +1 -1
- package/dist/types/types.js +234 -225
- package/dist/ui/ai-api.d.ts.map +1 -1
- package/dist/ui/ai-api.js +1 -1
- package/dist/ui/ai-client.d.ts.map +1 -1
- package/dist/ui/ai-client.js +28 -18
- package/dist/ui/api.d.ts.map +1 -1
- package/dist/ui/api.js +135 -128
- package/dist/ui/async-route.d.ts +3 -0
- package/dist/ui/async-route.d.ts.map +1 -0
- package/dist/ui/async-route.js +12 -0
- package/dist/ui/cdd-service.d.ts +9 -7
- package/dist/ui/cdd-service.d.ts.map +1 -1
- package/dist/ui/cdd-service.js +7 -5
- package/dist/ui/migrations-api.d.ts.map +1 -1
- package/dist/ui/migrations-api.js +17 -15
- package/dist/ui-web/assets/index-DV1AAq6W.js +178 -0
- package/dist/ui-web/index.html +1 -1
- package/dist/utils/formatter.d.ts.map +1 -1
- package/dist/utils/formatter.js +7 -5
- package/dist/utils/fs-utils.d.ts +3 -3
- package/dist/utils/fs-utils.d.ts.map +1 -1
- package/dist/utils/fs-utils.js +6 -6
- package/dist/utils/model.d.ts +3 -5
- package/dist/utils/model.d.ts.map +1 -1
- package/dist/utils/model.js +1 -1
- package/dist/utils/object-utils.d.ts +1 -1
- package/dist/utils/object-utils.d.ts.map +1 -1
- package/dist/utils/object-utils.js +17 -16
- package/dist/utils/process-utils.d.ts.map +1 -1
- package/dist/utils/process-utils.js +4 -2
- package/dist/utils/runtime-value.d.ts +13 -0
- package/dist/utils/runtime-value.d.ts.map +1 -0
- package/dist/utils/runtime-value.js +40 -0
- package/dist/utils/sql-parser.d.ts +8 -1
- package/dist/utils/sql-parser.d.ts.map +1 -1
- package/dist/utils/sql-parser.js +6 -3
- package/dist/utils/type-utils.d.ts.map +1 -1
- package/dist/utils/type-utils.js +10 -8
- package/dist/utils/utils.d.ts +2 -2
- package/dist/utils/utils.d.ts.map +1 -1
- package/dist/utils/utils.js +11 -8
- package/dist/utils/zod-error.d.ts.map +1 -1
- package/dist/utils/zod-error.js +7 -4
- package/dist/vector/chunking.d.ts.map +1 -1
- package/dist/vector/chunking.js +1 -1
- package/dist/vector/embedding.d.ts.map +1 -1
- package/dist/vector/embedding.js +1 -1
- package/dist/vector/types.d.ts +3 -2
- package/dist/vector/types.d.ts.map +1 -1
- package/package.json +5 -3
- package/src/ai/agents/agent.ts +5 -5
- package/src/ai/agents/types.ts +1 -1
- package/src/ai/providers/rtzr/__tests__/model.test.ts +2 -2
- package/src/ai/providers/rtzr/error.ts +5 -3
- package/src/ai/providers/rtzr/model.ts +3 -2
- package/src/ai/providers/rtzr/options.ts +10 -5
- package/src/ai/providers/rtzr/provider.ts +10 -10
- package/src/ai/providers/rtzr/utils.ts +3 -1
- package/src/api/__tests__/config.test.ts +11 -21
- package/src/api/__tests__/sonamu.http-validator.test.ts +512 -0
- package/src/api/__tests__/sonamu.websocket.test.ts +51 -41
- package/src/api/__tests__/zod-compiler-policy.test.ts +95 -0
- package/src/api/caster.ts +6 -8
- package/src/api/code-converters.ts +136 -36
- package/src/api/config.ts +62 -4
- package/src/api/context.ts +3 -3
- package/src/api/decorators.ts +28 -17
- package/src/api/http-validator.ts +149 -0
- package/src/api/sonamu.ts +459 -152
- package/src/api/websocket-helpers.ts +24 -17
- package/src/auth/audit-log/builders.ts +3 -2
- package/src/auth/audit-log/client-ip.ts +4 -2
- package/src/auth/audit-log/events.ts +15 -1
- package/src/auth/audit-log/plugin.ts +129 -200
- package/src/auth/audit-log-ingestor.ts +19 -15
- package/src/auth/auth-generator.ts +10 -5
- package/src/auth/better-auth-request.ts +4 -3
- package/src/auth/knex-adapter.ts +8 -2
- package/src/auth/plugins/entity-definitions/index.ts +6 -5
- package/src/bin/__tests__/http-validator-benchmark.test.ts +94 -0
- package/src/bin/__tests__/test-command.test.ts +9 -15
- package/src/bin/__tests__/ts-loader-register.test.ts +15 -17
- package/src/bin/__tests__/zod-compiler-build.test.ts +307 -0
- package/src/bin/build-config.ts +167 -0
- package/src/bin/cli.ts +153 -36
- package/src/bin/compiler-policy.ts +35 -0
- package/src/bin/fixture.ts +14 -3
- package/src/bin/test-command.ts +74 -29
- package/src/bin/ts-loader-registration.ts +22 -4
- package/src/cache/decorator.ts +10 -3
- package/src/compress/compress.ts +17 -4
- package/src/cone/cone-generator.ts +34 -6
- package/src/database/__tests__/db.test.ts +1 -0
- package/src/database/__tests__/puri.test.ts +16 -15
- package/src/database/__tests__/transaction-scope.test.ts +5 -0
- package/src/database/_batch_update.ts +1 -0
- package/src/database/base-model.ts +81 -50
- package/src/database/base-model.types.ts +6 -6
- package/src/database/db.ts +29 -19
- package/src/database/knex.ts +30 -17
- package/src/database/puri-subset.test-d.ts +17 -0
- package/src/database/puri.ts +181 -143
- package/src/database/puri.types.test-d.ts +31 -1
- package/src/database/puri.types.ts +23 -21
- package/src/database/upsert-builder.ts +75 -53
- package/src/dict/sd.ts +15 -5
- package/src/dict/sonamu-dictionary.ts +6 -6
- package/src/dict/utils.ts +9 -1
- package/src/entity/entity-manager.ts +26 -9
- package/src/entity/entity-template-cone.ts +5 -10
- package/src/entity/entity.ts +50 -34
- package/src/env.ts +7 -3
- package/src/exceptions/error-handler.ts +17 -2
- package/src/exceptions/so-exceptions.ts +26 -20
- package/src/filter/utils.ts +21 -11
- package/src/index.ts +3 -0
- package/src/logger/configure.ts +26 -18
- package/src/migration/__tests__/migrator.test.ts +50 -57
- package/src/migration/code-generation.ts +132 -104
- package/src/migration/index-where-predicate.ts +51 -24
- package/src/migration/migration-set.ts +11 -5
- package/src/migration/migrator.ts +68 -41
- package/src/migration/postgresql-schema-reader.ts +52 -47
- package/src/migration/slack-confirm.ts +17 -15
- package/src/naite/naite-reporter.ts +1 -1
- package/src/naite/naite.ts +97 -24
- package/src/runtime-type.ts +34 -0
- package/src/ssr/hmr-opt-out.ts +78 -0
- package/src/ssr/renderer.ts +6 -0
- package/src/storage/base-file.ts +13 -13
- package/src/storage/buffered-file.ts +11 -11
- package/src/storage/s3-driver.ts +4 -1
- package/src/storage/uploaded-file.ts +8 -8
- package/src/stream/__tests__/ws-contracts.test.ts +4 -2
- package/src/stream/__tests__/ws-telemetry.test.ts +1 -1
- package/src/stream/__tests__/ws.test.ts +30 -6
- package/src/stream/sse.ts +12 -11
- package/src/stream/ws-core.ts +1 -1
- package/src/stream/ws-delivery.ts +16 -7
- package/src/stream/ws-local-connection-store.ts +2 -3
- package/src/stream/ws-presence-store.ts +6 -1
- package/src/stream/ws-registry.ts +16 -7
- package/src/stream/ws-telemetry.ts +66 -43
- package/src/stream/ws.ts +73 -39
- package/src/syncer/__tests__/api-parser.websocket-type-ref.test.ts +3 -2
- package/src/syncer/__tests__/http-validator-registry.test.ts +137 -0
- package/src/syncer/api-parser.ts +67 -27
- package/src/syncer/checksum.ts +17 -11
- package/src/syncer/code-generator.ts +25 -17
- package/src/syncer/entity-operations.ts +3 -5
- package/src/syncer/file-copy.ts +46 -0
- package/src/syncer/file-patterns.ts +11 -8
- package/src/syncer/file-tracking.ts +3 -4
- package/src/syncer/filesystem-dependencies.ts +73 -0
- package/src/syncer/module-loader.ts +8 -4
- package/src/syncer/syncer-actions.ts +56 -18
- package/src/syncer/syncer.ts +116 -43
- package/src/syncer/watcher.ts +8 -4
- package/src/tasks/decorator.ts +20 -12
- package/src/tasks/step-wrapper.ts +19 -9
- package/src/tasks/workflow-manager.ts +15 -9
- package/src/template/__tests__/http_validators.template.test.ts +160 -0
- package/src/template/__tests__/services.template.mutation.test.ts +24 -23
- package/src/template/__tests__/services.template.websocket.test.ts +21 -25
- package/src/template/entity-converter.ts +5 -2
- package/src/template/helpers.ts +8 -9
- package/src/template/implementations/generated.template.ts +5 -4
- package/src/template/implementations/generated_http.template.ts +61 -15
- package/src/template/implementations/generated_sso.template.ts +15 -4
- package/src/template/implementations/http_validators.template.ts +175 -0
- package/src/template/implementations/model.template.ts +3 -1
- package/src/template/implementations/sd.template.ts +81 -41
- package/src/template/implementations/services.template.ts +2 -2
- package/src/template/implementations/view_form.template.ts +56 -39
- package/src/template/implementations/view_list.template.ts +31 -23
- package/src/template/template-manager.ts +15 -13
- package/src/template/template-types.ts +13 -5
- package/src/template/template.ts +4 -3
- package/src/template/zod-converter.ts +206 -91
- package/src/testing/__tests__/dev-test-routes.test.ts +85 -25
- package/src/testing/__tests__/dev-vitest-manager.test.ts +15 -15
- package/src/testing/_relation-graph.ts +4 -1
- package/src/testing/bootstrap.ts +12 -5
- package/src/testing/data-explorer.ts +102 -53
- package/src/testing/dev-test-routes.ts +87 -50
- package/src/testing/dev-vitest-manager.ts +88 -32
- package/src/testing/faker-mappings.ts +2 -2
- package/src/testing/filesystem.ts +1 -0
- package/src/testing/fixture-generator.ts +191 -131
- package/src/testing/fixture-loader.ts +5 -1
- package/src/testing/fixture-manager.ts +129 -90
- package/src/testing/global-setup.ts +7 -3
- package/src/testing/index.ts +5 -0
- package/src/types/__tests__/entity-json-schema-search-text.test.ts +9 -3
- package/src/types/types.ts +184 -158
- package/src/ui/ai-api.ts +9 -7
- package/src/ui/ai-client.ts +61 -56
- package/src/ui/api.ts +727 -616
- package/src/ui/async-route.ts +4 -0
- package/src/ui/cdd-service.ts +35 -12
- package/src/ui/migrations-api.ts +63 -51
- package/src/utils/formatter.ts +7 -3
- package/src/utils/fs-utils.ts +5 -5
- package/src/utils/model.ts +4 -5
- package/src/utils/object-utils.ts +32 -22
- package/src/utils/process-utils.ts +4 -1
- package/src/utils/runtime-value.ts +43 -0
- package/src/utils/sql-parser.ts +13 -6
- package/src/utils/type-utils.ts +9 -7
- package/src/utils/utils.ts +19 -21
- package/src/utils/zod-error.ts +4 -2
- package/src/vector/chunking.ts +6 -1
- package/src/vector/embedding.ts +2 -1
- package/src/vector/types.ts +4 -2
- package/tsdown.api.config.ts +5 -2
- package/dist/ui-web/assets/index-C0m1pk6K.js +0 -177
package/dist/api/sonamu.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { __esmMin } from "../_virtual/_rolldown/runtime.js";
|
|
2
|
+
import { init_runtime_value, isBigIntValue, isFunctionValue, isNumberValue, isObjectValue, isStringValue, isSymbolValue } from "../utils/runtime-value.js";
|
|
2
3
|
import { getSonamuEnvironment, init_env, readAllEnvironmentSnapshots } from "../env.js";
|
|
3
4
|
import { DB, init_db } from "../database/db.js";
|
|
4
5
|
import { BASE_FIELD_MAPPINGS, init_better_auth_entities } from "../auth/better-auth-entities.js";
|
|
@@ -8,6 +9,7 @@ import { CachePresets, applyCacheHeaders, init_cache_control } from "../cache-co
|
|
|
8
9
|
import { init_compress, toFastifyCompressOption } from "../compress/compress.js";
|
|
9
10
|
import { SD, init_sd, setSDConfig } from "../dict/sd.js";
|
|
10
11
|
import { NotFoundException, init_so_exceptions } from "../exceptions/so-exceptions.js";
|
|
12
|
+
import { init_runtime_type, runtimeTypeOf } from "../runtime-type.js";
|
|
11
13
|
import { BufferedFile, init_buffered_file } from "../storage/buffered-file.js";
|
|
12
14
|
import { UploadedFile, init_uploaded_file } from "../storage/uploaded-file.js";
|
|
13
15
|
import { createMockSSEFactory, init_sse } from "../stream/sse.js";
|
|
@@ -15,6 +17,8 @@ import { WebSocketRuntime, init_ws } from "../stream/ws.js";
|
|
|
15
17
|
import { centerText, init_console_util } from "../utils/console-util.js";
|
|
16
18
|
import { init_controller, isDaemonServer } from "../utils/controller.js";
|
|
17
19
|
import { exists, fileExists, init_fs_utils } from "../utils/fs-utils.js";
|
|
20
|
+
import { init_config, normalizeZodCompilerPolicy } from "./config.js";
|
|
21
|
+
import { assertHttpValidatorRegistry, createHttpValidator, getHttpValidatorRouteKey, init_http_validator } from "./http-validator.js";
|
|
18
22
|
import { getSecrets, init_secret } from "./secret.js";
|
|
19
23
|
import { createWebSocketReplyStub, init_websocket_helpers, resolveIntegratedViteHmrOptions, resolveWebSocketCloseDescriptor, resolveWebSocketPluginOptions } from "./websocket-helpers.js";
|
|
20
24
|
import { AsyncLocalStorage } from "async_hooks";
|
|
@@ -23,14 +27,40 @@ import path from "path";
|
|
|
23
27
|
import chalk from "chalk";
|
|
24
28
|
import fs from "fs/promises";
|
|
25
29
|
import os from "os";
|
|
30
|
+
import "@fastify/websocket";
|
|
26
31
|
import mime, { lookup } from "mime-types";
|
|
27
32
|
//#region src/api/sonamu.ts
|
|
33
|
+
function toApiArgument(value) {
|
|
34
|
+
if (value === null) return null;
|
|
35
|
+
if (value === void 0) return void 0;
|
|
36
|
+
if (value === true) return true;
|
|
37
|
+
if (value === false) return false;
|
|
38
|
+
if (isStringValue(value)) return value;
|
|
39
|
+
if (isNumberValue(value)) return value;
|
|
40
|
+
if (isBigIntValue(value)) return value;
|
|
41
|
+
if (isSymbolValue(value)) return value;
|
|
42
|
+
if (isFunctionValue(value)) return value;
|
|
43
|
+
if (isObjectValue(value)) return value;
|
|
44
|
+
throw new Error("지원하지 않는 API 인수 타입입니다.");
|
|
45
|
+
}
|
|
46
|
+
function toApiArgumentMap(value) {
|
|
47
|
+
return new Map(Object.entries(value).map(([key, item]) => [key, toApiArgument(item)]));
|
|
48
|
+
}
|
|
49
|
+
function createUnavailableSSE(_events) {
|
|
50
|
+
throw new Error("createSSE is not available in websocket context. Define websocketContextProvider if your context setup depends on SSE helpers.");
|
|
51
|
+
}
|
|
52
|
+
function printDimSummary(message) {
|
|
53
|
+
console.log(chalk.dim(`✓ ${message}`));
|
|
54
|
+
}
|
|
55
|
+
function printGreenSummary(message) {
|
|
56
|
+
console.log(chalk.green(`✓ ${message}`));
|
|
57
|
+
}
|
|
28
58
|
function getWebSocketTelemetryContext(ws) {
|
|
29
59
|
if (!isTelemetryContextProvider(ws)) return {};
|
|
30
60
|
return ws.getTelemetryContext();
|
|
31
61
|
}
|
|
32
62
|
function isTelemetryContextProvider(ws) {
|
|
33
|
-
return "getTelemetryContext" in ws &&
|
|
63
|
+
return "getTelemetryContext" in ws && isFunctionValue(ws.getTelemetryContext);
|
|
34
64
|
}
|
|
35
65
|
/**
|
|
36
66
|
* stream 모드에서 키 생성 함수가 지정되지 않았을 때 사용하는 기본 함수입니다.
|
|
@@ -48,7 +78,7 @@ function isLocalHost(host) {
|
|
|
48
78
|
function runGuards({ guards, config, request, api }) {
|
|
49
79
|
for (const guard of guards ?? []) config.guardHandler(guard, request, api);
|
|
50
80
|
}
|
|
51
|
-
var SonamuClass, Sonamu, LOCAL_HOSTS;
|
|
81
|
+
var defaultSonamuHttpValidatorDependencies, SonamuClass, Sonamu, LOCAL_HOSTS;
|
|
52
82
|
var init_sonamu = __esmMin((() => {
|
|
53
83
|
init_better_auth_entities();
|
|
54
84
|
init_better_auth_request();
|
|
@@ -58,6 +88,7 @@ var init_sonamu = __esmMin((() => {
|
|
|
58
88
|
init_sd();
|
|
59
89
|
init_env();
|
|
60
90
|
init_so_exceptions();
|
|
91
|
+
init_runtime_type();
|
|
61
92
|
init_buffered_file();
|
|
62
93
|
init_uploaded_file();
|
|
63
94
|
init_sse();
|
|
@@ -65,13 +96,25 @@ var init_sonamu = __esmMin((() => {
|
|
|
65
96
|
init_console_util();
|
|
66
97
|
init_controller();
|
|
67
98
|
init_fs_utils();
|
|
99
|
+
init_runtime_value();
|
|
68
100
|
init_utils();
|
|
101
|
+
init_config();
|
|
102
|
+
init_http_validator();
|
|
69
103
|
init_secret();
|
|
70
104
|
init_websocket_helpers();
|
|
105
|
+
defaultSonamuHttpValidatorDependencies = {
|
|
106
|
+
createValidator: createHttpValidator,
|
|
107
|
+
assertRegistry: assertHttpValidatorRegistry
|
|
108
|
+
};
|
|
71
109
|
SonamuClass = class {
|
|
72
110
|
isInitialized = false;
|
|
73
111
|
forTesting = false;
|
|
74
112
|
asyncLocalStorage = new AsyncLocalStorage();
|
|
113
|
+
httpValidators = /* @__PURE__ */ new WeakMap();
|
|
114
|
+
pendingHttpValidators = /* @__PURE__ */ new WeakMap();
|
|
115
|
+
aotHttpValidatorRegistry;
|
|
116
|
+
preparedApis = [];
|
|
117
|
+
preparedModels = {};
|
|
75
118
|
getContext() {
|
|
76
119
|
const store = this.asyncLocalStorage.getStore();
|
|
77
120
|
if (store?.context) return store.context;
|
|
@@ -88,83 +131,107 @@ var init_sonamu = __esmMin((() => {
|
|
|
88
131
|
};
|
|
89
132
|
else throw new Error("Sonamu cannot find context");
|
|
90
133
|
}
|
|
91
|
-
|
|
134
|
+
apiRootPathValue = null;
|
|
92
135
|
set apiRootPath(apiRootPath) {
|
|
93
|
-
this.
|
|
136
|
+
this.apiRootPathValue = apiRootPath;
|
|
94
137
|
}
|
|
95
138
|
get apiRootPath() {
|
|
96
|
-
if (this.
|
|
97
|
-
return this.
|
|
139
|
+
if (this.apiRootPathValue === null) throw new Error("Sonamu has not been initialized");
|
|
140
|
+
return this.apiRootPathValue;
|
|
98
141
|
}
|
|
99
142
|
get appRootPath() {
|
|
100
143
|
return this.apiRootPath.split(path.sep).slice(0, -1).join(path.sep);
|
|
101
144
|
}
|
|
102
|
-
|
|
145
|
+
dbConfigValue = null;
|
|
103
146
|
set dbConfig(dbConfig) {
|
|
104
|
-
this.
|
|
147
|
+
this.dbConfigValue = dbConfig;
|
|
105
148
|
}
|
|
106
149
|
get dbConfig() {
|
|
107
|
-
if (this.
|
|
108
|
-
return this.
|
|
150
|
+
if (this.dbConfigValue === null) throw new Error("Sonamu has not been initialized");
|
|
151
|
+
return this.dbConfigValue;
|
|
109
152
|
}
|
|
110
|
-
|
|
153
|
+
syncerValue = null;
|
|
111
154
|
set syncer(syncer) {
|
|
112
|
-
this.
|
|
155
|
+
this.syncerValue = syncer;
|
|
113
156
|
}
|
|
114
157
|
get syncer() {
|
|
115
|
-
if (this.
|
|
116
|
-
return this.
|
|
158
|
+
if (this.syncerValue === null) throw new Error("Sonamu has not been initialized");
|
|
159
|
+
return this.syncerValue;
|
|
117
160
|
}
|
|
118
|
-
|
|
161
|
+
configValue = null;
|
|
119
162
|
set config(config) {
|
|
120
|
-
this.
|
|
163
|
+
this.configValue = config;
|
|
121
164
|
}
|
|
122
165
|
get config() {
|
|
123
|
-
if (this.
|
|
124
|
-
return this.
|
|
166
|
+
if (this.configValue === null) throw new Error("Sonamu has not been initialized");
|
|
167
|
+
return this.configValue;
|
|
125
168
|
}
|
|
126
169
|
secrets = getSecrets();
|
|
127
|
-
|
|
170
|
+
storageValue = null;
|
|
128
171
|
/**
|
|
129
172
|
* StorageManager 인스턴스
|
|
130
173
|
*/
|
|
131
174
|
get storage() {
|
|
132
|
-
if (!this.
|
|
133
|
-
return this.
|
|
175
|
+
if (!this.storageValue) throw new Error("Storage has not been initialized. Check storage config.");
|
|
176
|
+
return this.storageValue;
|
|
134
177
|
}
|
|
135
|
-
|
|
178
|
+
cacheValue = null;
|
|
136
179
|
/**
|
|
137
180
|
* CacheManager 인스턴스 (BentoCache)
|
|
138
181
|
*/
|
|
139
182
|
get cache() {
|
|
140
|
-
if (!this.
|
|
141
|
-
return this.
|
|
183
|
+
if (!this.cacheValue) throw new Error("Cache has not been initialized. Check cache config in sonamu.config.ts.");
|
|
184
|
+
return this.cacheValue;
|
|
142
185
|
}
|
|
143
|
-
|
|
186
|
+
workflowsValue = null;
|
|
144
187
|
get workflows() {
|
|
145
|
-
if (this.
|
|
146
|
-
return this.
|
|
188
|
+
if (this.workflowsValue === null) throw new Error("Sonamu has not been initialized");
|
|
189
|
+
return this.workflowsValue;
|
|
147
190
|
}
|
|
148
|
-
|
|
191
|
+
authValue = null;
|
|
149
192
|
get auth() {
|
|
150
|
-
if (!this.
|
|
151
|
-
return this.
|
|
193
|
+
if (!this.authValue) throw new Error("Auth has not been initialized. Check auth config in sonamu.config.ts.");
|
|
194
|
+
return this.authValue;
|
|
152
195
|
}
|
|
153
|
-
|
|
196
|
+
devVitestManagerValue = null;
|
|
154
197
|
get devVitestManager() {
|
|
155
|
-
return this.
|
|
198
|
+
return this.devVitestManagerValue;
|
|
156
199
|
}
|
|
157
200
|
set devVitestManager(manager) {
|
|
158
|
-
this.
|
|
201
|
+
this.devVitestManagerValue = manager;
|
|
159
202
|
}
|
|
160
|
-
|
|
203
|
+
websocketRuntimeValue = null;
|
|
161
204
|
websocketPluginServers = /* @__PURE__ */ new WeakSet();
|
|
162
205
|
get websocketRuntime() {
|
|
163
|
-
if (!this.
|
|
164
|
-
return this.
|
|
206
|
+
if (!this.websocketRuntimeValue) throw new Error("WebSocket runtime has not been initialized.");
|
|
207
|
+
return this.websocketRuntimeValue;
|
|
165
208
|
}
|
|
166
209
|
set websocketRuntime(runtime) {
|
|
167
|
-
this.
|
|
210
|
+
this.websocketRuntimeValue = runtime;
|
|
211
|
+
}
|
|
212
|
+
captureTestingSnapshot() {
|
|
213
|
+
return {
|
|
214
|
+
apiRootPath: this.apiRootPathValue,
|
|
215
|
+
config: this.configValue,
|
|
216
|
+
syncer: this.syncerValue,
|
|
217
|
+
httpValidators: this.httpValidators,
|
|
218
|
+
pendingHttpValidators: this.pendingHttpValidators,
|
|
219
|
+
aotHttpValidatorRegistry: this.aotHttpValidatorRegistry,
|
|
220
|
+
preparedApis: this.preparedApis,
|
|
221
|
+
preparedModels: this.preparedModels,
|
|
222
|
+
websocketRuntime: this.websocketRuntimeValue
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
restoreTestingSnapshot(snapshot) {
|
|
226
|
+
this.apiRootPathValue = snapshot.apiRootPath;
|
|
227
|
+
this.configValue = snapshot.config;
|
|
228
|
+
this.syncerValue = snapshot.syncer;
|
|
229
|
+
this.httpValidators = snapshot.httpValidators;
|
|
230
|
+
this.pendingHttpValidators = snapshot.pendingHttpValidators;
|
|
231
|
+
this.aotHttpValidatorRegistry = snapshot.aotHttpValidatorRegistry;
|
|
232
|
+
this.preparedApis = snapshot.preparedApis;
|
|
233
|
+
this.preparedModels = snapshot.preparedModels;
|
|
234
|
+
this.websocketRuntimeValue = snapshot.websocketRuntime;
|
|
168
235
|
}
|
|
169
236
|
watcher = null;
|
|
170
237
|
server = null;
|
|
@@ -188,11 +255,11 @@ var init_sonamu = __esmMin((() => {
|
|
|
188
255
|
this.config.database.defaultOptions.client = this.config.database.database ?? "pg";
|
|
189
256
|
const { configureLogTape } = await import("../logger/configure.js");
|
|
190
257
|
if (this.config.logging !== false) await configureLogTape({ ...this.config.logging });
|
|
191
|
-
const { DB } = await import("../database/db.js");
|
|
258
|
+
const { DB: RuntimeDB } = await import("../database/db.js");
|
|
192
259
|
const { isLocal: isLocalEnvironment } = await import("../utils/controller.js");
|
|
193
260
|
const environmentSnapshots = isLocalEnvironment() ? readAllEnvironmentSnapshots(this.apiRootPath, baseEnvBeforeConfigLoad) : void 0;
|
|
194
|
-
this.dbConfig =
|
|
195
|
-
|
|
261
|
+
this.dbConfig = RuntimeDB.generateDBConfig(this.config.database, this.config.projectName, environmentSnapshots);
|
|
262
|
+
RuntimeDB.setConfig(this.dbConfig);
|
|
196
263
|
const { EntityManager } = await import("../entity/entity-manager.js");
|
|
197
264
|
await EntityManager.autoload(doSilent);
|
|
198
265
|
await this.initializeCache(this.config.server.cache, forTesting);
|
|
@@ -205,7 +272,7 @@ var init_sonamu = __esmMin((() => {
|
|
|
205
272
|
database: sonamuKnexAdapter(),
|
|
206
273
|
...mergedFieldMappings
|
|
207
274
|
};
|
|
208
|
-
this.
|
|
275
|
+
this.authValue = betterAuth(authOptions);
|
|
209
276
|
}
|
|
210
277
|
if (forTesting) {
|
|
211
278
|
this.isInitialized = true;
|
|
@@ -227,11 +294,11 @@ var init_sonamu = __esmMin((() => {
|
|
|
227
294
|
await this.startWatcher();
|
|
228
295
|
}
|
|
229
296
|
this.isInitialized = true;
|
|
230
|
-
this.
|
|
231
|
-
this.
|
|
297
|
+
this.initElapsed = performance.now() - initStart;
|
|
298
|
+
this.configElapsed = configTime;
|
|
232
299
|
}
|
|
233
|
-
|
|
234
|
-
|
|
300
|
+
initElapsed = 0;
|
|
301
|
+
configElapsed = 0;
|
|
235
302
|
async createServer(initOptions) {
|
|
236
303
|
if (!this.isInitialized) await this.init(initOptions?.doSilent, initOptions?.enableSync);
|
|
237
304
|
const options = this.config.server;
|
|
@@ -245,7 +312,7 @@ var init_sonamu = __esmMin((() => {
|
|
|
245
312
|
this.websocketRuntime = new WebSocketRuntime(options.websocket);
|
|
246
313
|
if (options.storage) {
|
|
247
314
|
const { StorageManager } = await import("../storage/storage-manager.js");
|
|
248
|
-
this.
|
|
315
|
+
this.storageValue = new StorageManager(options.storage);
|
|
249
316
|
}
|
|
250
317
|
if (options.plugins) await this.registerPlugins(server, options.plugins);
|
|
251
318
|
if (options.auth) await this.registerBetterAuth(server, options.auth);
|
|
@@ -261,6 +328,7 @@ var init_sonamu = __esmMin((() => {
|
|
|
261
328
|
if (!this.isInitialized) await this.init(options?.doSilent, options?.enableSync);
|
|
262
329
|
this.server = server;
|
|
263
330
|
this.websocketRuntime ??= new WebSocketRuntime(this.config.server.websocket);
|
|
331
|
+
await this.refreshHttpValidators();
|
|
264
332
|
const timezone = this.config.api.timezone;
|
|
265
333
|
if (timezone) {
|
|
266
334
|
const { formatInTimeZone } = await import("date-fns-tz");
|
|
@@ -268,7 +336,7 @@ var init_sonamu = __esmMin((() => {
|
|
|
268
336
|
const DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ssXXX";
|
|
269
337
|
server.setReplySerializer((payload) => {
|
|
270
338
|
return JSON.stringify(payload, (_key, value) => {
|
|
271
|
-
if (
|
|
339
|
+
if (isStringValue(value) && ISO_DATE_REGEX.test(value)) return formatInTimeZone(new Date(value), timezone, DATE_FORMAT);
|
|
272
340
|
return value;
|
|
273
341
|
});
|
|
274
342
|
});
|
|
@@ -322,7 +390,7 @@ var init_sonamu = __esmMin((() => {
|
|
|
322
390
|
server.route({
|
|
323
391
|
method: api.options.httpMethod ?? "GET",
|
|
324
392
|
url: this.config.api.route.prefix + api.path,
|
|
325
|
-
handler: this.createApiHandler(api, config),
|
|
393
|
+
handler: await this.createApiHandler(api, config),
|
|
326
394
|
compress: toFastifyCompressOption(api.options.compress, globalCompressOptions)
|
|
327
395
|
});
|
|
328
396
|
}
|
|
@@ -330,24 +398,24 @@ var init_sonamu = __esmMin((() => {
|
|
|
330
398
|
}
|
|
331
399
|
}
|
|
332
400
|
/**
|
|
333
|
-
* dev 모드 공통: catch-all에서
|
|
401
|
+
* dev 모드 공통: catch-all에서 마지막 준비 완료 API snapshot을 탐색하여 요청을 처리합니다.
|
|
334
402
|
* server.route()로 개별 등록하면 handler가 고정되어 HMR이 동작하지 않으므로,
|
|
335
|
-
*
|
|
403
|
+
* refresh 성공 시 교체되는 snapshot을 매 요청 조회합니다.
|
|
336
404
|
*
|
|
337
405
|
* 요청이 /api(정확히는 this.config.api.route.prefix)로 시작하지 않는 경우라면 null을 반환하며 끝냅니다.
|
|
338
406
|
*/
|
|
339
|
-
handleDevApiRequest(request, config) {
|
|
340
|
-
const matchedApi = this.findMatchedApi(request);
|
|
407
|
+
async handleDevApiRequest(request, config) {
|
|
408
|
+
const matchedApi = this.findMatchedApi(request, this.preparedApis, this.preparedModels);
|
|
341
409
|
if (!matchedApi) throw new NotFoundException(SD("error.api.notFound"));
|
|
342
410
|
if (matchedApi.websocketOptions) return this.createWebSocketUpgradeRequiredHandler();
|
|
343
|
-
return this.createApiHandler(matchedApi, config);
|
|
411
|
+
return await this.createApiHandler(matchedApi, config, this.preparedModels);
|
|
344
412
|
}
|
|
345
|
-
findMatchedApi(request) {
|
|
413
|
+
findMatchedApi(request, apis, models) {
|
|
346
414
|
const url = this.getPathnameFromUrl(request.url);
|
|
347
415
|
const method = request.method;
|
|
348
416
|
if (!url.startsWith(this.config.api.route.prefix)) return;
|
|
349
|
-
return
|
|
350
|
-
if (
|
|
417
|
+
return apis.find((api) => {
|
|
418
|
+
if (models[api.modelName] === void 0) return false;
|
|
351
419
|
if ((api.options.httpMethod ?? "GET") !== method) return false;
|
|
352
420
|
const fullPath = this.config.api.route.prefix + api.path;
|
|
353
421
|
return this.isPathPatternMatch(fullPath, url);
|
|
@@ -355,14 +423,14 @@ var init_sonamu = __esmMin((() => {
|
|
|
355
423
|
}
|
|
356
424
|
/**
|
|
357
425
|
* dev api 모드: Vite 없이 API 동적 라우팅만 제공합니다.
|
|
358
|
-
* HMR을 위해 catch-all에서 매 요청마다
|
|
426
|
+
* HMR을 위해 catch-all에서 매 요청마다 준비 완료 API snapshot을 조회합니다.
|
|
359
427
|
*/
|
|
360
428
|
setupDevServer(server, config) {
|
|
361
429
|
server.route({
|
|
362
430
|
method: "GET",
|
|
363
431
|
url: `${this.config.api.route.prefix}/*`,
|
|
364
432
|
handler: async (request, reply) => {
|
|
365
|
-
const handler = this.handleDevApiRequest(request, config);
|
|
433
|
+
const handler = await this.handleDevApiRequest(request, config);
|
|
366
434
|
if (handler) return handler(request, reply);
|
|
367
435
|
throw new NotFoundException(SD("error.api.notFound"));
|
|
368
436
|
},
|
|
@@ -380,7 +448,7 @@ var init_sonamu = __esmMin((() => {
|
|
|
380
448
|
],
|
|
381
449
|
url: `${this.config.api.route.prefix}/*`,
|
|
382
450
|
handler: async (request, reply) => {
|
|
383
|
-
const handler = this.handleDevApiRequest(request, config);
|
|
451
|
+
const handler = await this.handleDevApiRequest(request, config);
|
|
384
452
|
if (handler) return handler(request, reply);
|
|
385
453
|
throw new NotFoundException(SD("error.api.notFound"));
|
|
386
454
|
}
|
|
@@ -415,7 +483,7 @@ var init_sonamu = __esmMin((() => {
|
|
|
415
483
|
method: "GET",
|
|
416
484
|
url: `${this.config.api.route.prefix}/*`,
|
|
417
485
|
handler: async (request, reply) => {
|
|
418
|
-
const result = this.handleDevApiRequest(request, config);
|
|
486
|
+
const result = await this.handleDevApiRequest(request, config);
|
|
419
487
|
if (result) return result(request, reply);
|
|
420
488
|
throw new NotFoundException(SD("error.api.notFound"));
|
|
421
489
|
},
|
|
@@ -433,7 +501,7 @@ var init_sonamu = __esmMin((() => {
|
|
|
433
501
|
],
|
|
434
502
|
url: `${this.config.api.route.prefix}/*`,
|
|
435
503
|
handler: async (request, reply) => {
|
|
436
|
-
const result = this.handleDevApiRequest(request, config);
|
|
504
|
+
const result = await this.handleDevApiRequest(request, config);
|
|
437
505
|
if (result) return result(request, reply);
|
|
438
506
|
throw new NotFoundException(SD("error.api.notFound"));
|
|
439
507
|
}
|
|
@@ -452,8 +520,10 @@ var init_sonamu = __esmMin((() => {
|
|
|
452
520
|
return html;
|
|
453
521
|
}
|
|
454
522
|
try {
|
|
455
|
-
let template = await
|
|
523
|
+
let template = await fs.readFile(path.join(this.viteServer.config.root, "index.html"), "utf-8");
|
|
456
524
|
template = await this.viteServer.transformIndexHtml(url, template);
|
|
525
|
+
const { HMR_OPT_OUT_SCRIPT, isHmrDisabledByQuery } = await import("../ssr/hmr-opt-out.js");
|
|
526
|
+
if (isHmrDisabledByQuery(url)) template = template.replace("<head>", `<head>\n${HMR_OPT_OUT_SCRIPT}`);
|
|
457
527
|
reply.type("text/html");
|
|
458
528
|
return template;
|
|
459
529
|
} catch (e) {
|
|
@@ -467,7 +537,6 @@ var init_sonamu = __esmMin((() => {
|
|
|
467
537
|
server.addHook("onClose", async () => {
|
|
468
538
|
await this.viteServer.close();
|
|
469
539
|
});
|
|
470
|
-
const chalk = (await import("chalk")).default;
|
|
471
540
|
if ("port" in hmr) console.log(chalk.dim(`✓ Vite HMR using dedicated websocket port ${hmr.port} to avoid Fastify websocket conflicts`));
|
|
472
541
|
console.log(chalk.dim("✓ Vite dev server integrated"));
|
|
473
542
|
}
|
|
@@ -584,8 +653,10 @@ var init_sonamu = __esmMin((() => {
|
|
|
584
653
|
});
|
|
585
654
|
console.log(`✓ Static web server configured with ${ssrAvailable ? "SSR" : "CSR only"} support`);
|
|
586
655
|
}
|
|
587
|
-
createApiHandler(api, config) {
|
|
656
|
+
createApiHandler(api, config, models = this.syncer.models, dependencies = defaultSonamuHttpValidatorDependencies) {
|
|
657
|
+
const preparedValidator = this.getOrCreateHttpValidator(api, dependencies);
|
|
588
658
|
return async (request, reply) => {
|
|
659
|
+
const validator = preparedValidator instanceof Promise ? await preparedValidator : preparedValidator;
|
|
589
660
|
const context = await this.createContext(config, request, reply);
|
|
590
661
|
return this.asyncLocalStorage.run({ context }, async () => {
|
|
591
662
|
runGuards({
|
|
@@ -594,10 +665,8 @@ var init_sonamu = __esmMin((() => {
|
|
|
594
665
|
request,
|
|
595
666
|
api
|
|
596
667
|
});
|
|
597
|
-
const { getZodObjectFromApi } = await import("./code-converters.js");
|
|
598
|
-
const ReqType = getZodObjectFromApi(api, this.syncer.types);
|
|
599
668
|
const which = api.options.httpMethod === "GET" ? "query" : "body";
|
|
600
|
-
let reqBody;
|
|
669
|
+
let reqBody = /* @__PURE__ */ new Map();
|
|
601
670
|
const files = {
|
|
602
671
|
bufferedFiles: [],
|
|
603
672
|
uploadedFiles: []
|
|
@@ -638,8 +707,7 @@ var init_sonamu = __esmMin((() => {
|
|
|
638
707
|
const parsed = (await import("qs")).default.parse(fields);
|
|
639
708
|
Object.assign(body, parsed);
|
|
640
709
|
}
|
|
641
|
-
|
|
642
|
-
reqBody = fastifyCaster(ReqType).parse(body);
|
|
710
|
+
reqBody = toApiArgumentMap(validator.parse(body));
|
|
643
711
|
} catch (e) {
|
|
644
712
|
const { ZodError } = await import("zod");
|
|
645
713
|
if (e instanceof ZodError) {
|
|
@@ -660,19 +728,90 @@ var init_sonamu = __esmMin((() => {
|
|
|
660
728
|
const { ApiParamType } = await import("../types/types.js");
|
|
661
729
|
const args = api.parameters.map((param) => {
|
|
662
730
|
if (ApiParamType.isContext(param.type)) return context;
|
|
663
|
-
else return reqBody
|
|
731
|
+
else return reqBody.get(param.name);
|
|
664
732
|
});
|
|
665
|
-
return this.invokeModelMethod(api, args, reply);
|
|
733
|
+
return this.invokeModelMethod(api, args, reply, models);
|
|
666
734
|
});
|
|
667
735
|
};
|
|
668
736
|
}
|
|
737
|
+
getOrCreateHttpValidator(api, dependencies) {
|
|
738
|
+
const cached = this.httpValidators.get(api);
|
|
739
|
+
if (cached !== void 0) return cached;
|
|
740
|
+
const existing = this.pendingHttpValidators.get(api);
|
|
741
|
+
if (existing !== void 0) return existing;
|
|
742
|
+
const pending = this.buildHttpValidator(api, dependencies);
|
|
743
|
+
this.pendingHttpValidators.set(api, pending);
|
|
744
|
+
pending.then((validator) => {
|
|
745
|
+
this.httpValidators.set(api, validator);
|
|
746
|
+
this.pendingHttpValidators.delete(api);
|
|
747
|
+
}, () => {
|
|
748
|
+
this.pendingHttpValidators.delete(api);
|
|
749
|
+
});
|
|
750
|
+
return pending;
|
|
751
|
+
}
|
|
752
|
+
async buildHttpValidator(api, dependencies) {
|
|
753
|
+
const policy = normalizeZodCompilerPolicy(this.config.validation?.zodCompiler);
|
|
754
|
+
const sourceAot = process.env.HOT === "yes" || process.env.VITEST === "true";
|
|
755
|
+
if (policy.api === "aot" && !sourceAot) {
|
|
756
|
+
const registry = this.aotHttpValidatorRegistry ?? await this.loadAotHttpValidatorRegistry();
|
|
757
|
+
return this.getAotHttpValidator(api, registry);
|
|
758
|
+
}
|
|
759
|
+
return await dependencies.createValidator({
|
|
760
|
+
api,
|
|
761
|
+
policy,
|
|
762
|
+
types: this.syncer.types,
|
|
763
|
+
allowAotSourceFallback: sourceAot
|
|
764
|
+
});
|
|
765
|
+
}
|
|
766
|
+
getAotHttpValidator(api, registry) {
|
|
767
|
+
const routeKey = getHttpValidatorRouteKey(api);
|
|
768
|
+
const validator = registry.validators.get(routeKey);
|
|
769
|
+
if (validator === void 0) throw new Error(`HTTP validator registry is missing ${routeKey}`);
|
|
770
|
+
return validator;
|
|
771
|
+
}
|
|
772
|
+
async loadAotHttpValidatorRegistry(apis = this.syncer.apis, dependencies = defaultSonamuHttpValidatorDependencies) {
|
|
773
|
+
const { pathToFileURL } = await import("node:url");
|
|
774
|
+
const registryPath = path.join(this.apiRootPath, "dist/application/sonamu.validators.generated.js");
|
|
775
|
+
if (!await exists(registryPath)) throw new Error(`Generated HTTP validator registry not found: ${registryPath}`);
|
|
776
|
+
const imported = await import(pathToFileURL(registryPath).href);
|
|
777
|
+
if (!isStringValue(imported.fingerprint) || !(imported.validators instanceof Map)) throw new Error(`Invalid generated HTTP validator registry: ${registryPath}`);
|
|
778
|
+
for (const [key, validator] of imported.validators) if (!isStringValue(key) || !isObjectValue(validator) || validator === null || !("parse" in validator) || !isFunctionValue(validator.parse)) throw new Error(`Invalid HTTP validator registry entry: ${String(key)}`);
|
|
779
|
+
const registry = {
|
|
780
|
+
fingerprint: imported.fingerprint,
|
|
781
|
+
validators: imported.validators
|
|
782
|
+
};
|
|
783
|
+
dependencies.assertRegistry(apis, registry);
|
|
784
|
+
return registry;
|
|
785
|
+
}
|
|
786
|
+
async refreshHttpValidators(dependencies = defaultSonamuHttpValidatorDependencies) {
|
|
787
|
+
const policy = normalizeZodCompilerPolicy(this.config.validation?.zodCompiler);
|
|
788
|
+
const sourceAot = process.env.HOT === "yes" || process.env.VITEST === "true";
|
|
789
|
+
const nextApis = [...this.syncer.apis];
|
|
790
|
+
const nextModels = { ...this.syncer.models };
|
|
791
|
+
const restApis = nextApis.filter((api) => api.websocketOptions === void 0);
|
|
792
|
+
const next = /* @__PURE__ */ new WeakMap();
|
|
793
|
+
let nextAotRegistry;
|
|
794
|
+
if (policy.api === "aot" && !sourceAot) {
|
|
795
|
+
const registry = await this.loadAotHttpValidatorRegistry(nextApis, dependencies);
|
|
796
|
+
for (const api of restApis) next.set(api, this.getAotHttpValidator(api, registry));
|
|
797
|
+
nextAotRegistry = registry;
|
|
798
|
+
} else await Promise.all(restApis.map(async (api) => {
|
|
799
|
+
const validator = await this.buildHttpValidator(api, dependencies);
|
|
800
|
+
next.set(api, validator);
|
|
801
|
+
}));
|
|
802
|
+
this.httpValidators = next;
|
|
803
|
+
this.pendingHttpValidators = /* @__PURE__ */ new WeakMap();
|
|
804
|
+
this.aotHttpValidatorRegistry = nextAotRegistry;
|
|
805
|
+
this.preparedApis = nextApis;
|
|
806
|
+
this.preparedModels = nextModels;
|
|
807
|
+
}
|
|
669
808
|
createWebSocketUpgradeRequiredHandler() {
|
|
670
809
|
return async (_request, reply) => {
|
|
671
810
|
reply.header("connection", "Upgrade").header("upgrade", "websocket").status(426).send({ message: "WebSocket upgrade required" });
|
|
672
811
|
};
|
|
673
812
|
}
|
|
674
813
|
async handleDevWebSocketRequest(socket, request, config) {
|
|
675
|
-
const matchedApi = this.findMatchedApi(request);
|
|
814
|
+
const matchedApi = this.findMatchedApi(request, this.syncer.apis, this.syncer.models);
|
|
676
815
|
if (!matchedApi?.websocketOptions) {
|
|
677
816
|
const traceContext = this.websocketRuntime.telemetryController.createConnectionContext({ headers: request.headers });
|
|
678
817
|
this.websocketRuntime.telemetryController.emit({
|
|
@@ -692,6 +831,9 @@ var init_sonamu = __esmMin((() => {
|
|
|
692
831
|
}
|
|
693
832
|
await this.createWebSocketHandler(matchedApi, config)({ socket }, request);
|
|
694
833
|
}
|
|
834
|
+
createWebSocketHandlerForTesting(api, config) {
|
|
835
|
+
return this.createWebSocketHandler(api, config);
|
|
836
|
+
}
|
|
695
837
|
createWebSocketHandler(api, config) {
|
|
696
838
|
return async (connection, request) => {
|
|
697
839
|
const socket = connection.socket;
|
|
@@ -730,7 +872,7 @@ var init_sonamu = __esmMin((() => {
|
|
|
730
872
|
const { ApiParamType } = await import("../types/types.js");
|
|
731
873
|
const args = api.parameters.map((param) => {
|
|
732
874
|
if (ApiParamType.isContext(param.type)) return wsContext;
|
|
733
|
-
return reqBody
|
|
875
|
+
return reqBody.get(param.name);
|
|
734
876
|
});
|
|
735
877
|
await this.asyncLocalStorage.run({ context: wsContext }, async () => {
|
|
736
878
|
await this.invokeModelMethod(api, args);
|
|
@@ -767,7 +909,7 @@ var init_sonamu = __esmMin((() => {
|
|
|
767
909
|
};
|
|
768
910
|
}
|
|
769
911
|
createScopedWebSocketConnection(ws, getContext) {
|
|
770
|
-
const telemetryController = this.
|
|
912
|
+
const telemetryController = this.websocketRuntimeValue?.telemetryController;
|
|
771
913
|
const runInContext = (callback) => {
|
|
772
914
|
const context = getContext();
|
|
773
915
|
if (!context) return callback();
|
|
@@ -854,7 +996,7 @@ var init_sonamu = __esmMin((() => {
|
|
|
854
996
|
namespace: ws.namespace,
|
|
855
997
|
userId: ws.userId,
|
|
856
998
|
attributes: { event: eventName },
|
|
857
|
-
errorType: error instanceof Error ? error.name :
|
|
999
|
+
errorType: error instanceof Error ? error.name : runtimeTypeOf(error),
|
|
858
1000
|
...traceContext
|
|
859
1001
|
});
|
|
860
1002
|
throw error;
|
|
@@ -881,12 +1023,15 @@ var init_sonamu = __esmMin((() => {
|
|
|
881
1023
|
}
|
|
882
1024
|
};
|
|
883
1025
|
}
|
|
1026
|
+
createScopedWebSocketConnectionForTesting(ws, getContext) {
|
|
1027
|
+
return this.createScopedWebSocketConnection(ws, getContext);
|
|
1028
|
+
}
|
|
884
1029
|
async parseWebSocketRequestParams(api, request) {
|
|
885
1030
|
const { getZodObjectFromApi } = await import("./code-converters.js");
|
|
886
1031
|
const ReqType = getZodObjectFromApi(api, this.syncer.types);
|
|
887
1032
|
try {
|
|
888
1033
|
const { fastifyCaster } = await import("./caster.js");
|
|
889
|
-
return fastifyCaster(ReqType).parse(request.query ?? {});
|
|
1034
|
+
return toApiArgumentMap(fastifyCaster(ReqType).parse(request.query ?? {}));
|
|
890
1035
|
} catch (e) {
|
|
891
1036
|
const { ZodError } = await import("zod");
|
|
892
1037
|
if (e instanceof ZodError) {
|
|
@@ -972,9 +1117,15 @@ var init_sonamu = __esmMin((() => {
|
|
|
972
1117
|
return this.invokeModelMethod(api, args, reply);
|
|
973
1118
|
});
|
|
974
1119
|
}
|
|
975
|
-
async
|
|
976
|
-
|
|
977
|
-
|
|
1120
|
+
async handleDevApiRequestForTesting(request, config) {
|
|
1121
|
+
return await this.handleDevApiRequest(request, config);
|
|
1122
|
+
}
|
|
1123
|
+
async invokeModelMethod(api, args, reply, models = this.syncer.models) {
|
|
1124
|
+
const model = models[api.modelName];
|
|
1125
|
+
if (model === void 0) throw new Error(`Model not found: ${api.modelName}`);
|
|
1126
|
+
const method = model[api.methodName];
|
|
1127
|
+
if (!isFunctionValue(method)) throw new Error(`Model method not found: ${api.modelName}.${api.methodName}`);
|
|
1128
|
+
const result = await Function.prototype.apply.call(method, model, args);
|
|
978
1129
|
reply?.type(api.options.contentType ?? "application/json");
|
|
979
1130
|
return result;
|
|
980
1131
|
}
|
|
@@ -983,7 +1134,7 @@ var init_sonamu = __esmMin((() => {
|
|
|
983
1134
|
const createSSE = ((_request, _reply, _events) => createSSEFactory(_request.socket, _reply, _events)).bind(null, request, reply);
|
|
984
1135
|
const locale = this.detectLocale(request.headers["accept-language"], this.config.i18n.supportedLocales) ?? this.config.i18n.defaultLocale;
|
|
985
1136
|
const headers = convertFastifyHeadersToStandard(request.headers);
|
|
986
|
-
const session = await this.
|
|
1137
|
+
const session = await this.authValue?.api.getSession({ headers }) ?? null;
|
|
987
1138
|
return await Promise.resolve(config.contextProvider({
|
|
988
1139
|
transport: "http",
|
|
989
1140
|
request,
|
|
@@ -999,7 +1150,7 @@ var init_sonamu = __esmMin((() => {
|
|
|
999
1150
|
async createWebSocketContext(config, request, ws) {
|
|
1000
1151
|
const locale = this.detectLocale(request.headers["accept-language"], this.config.i18n.supportedLocales) ?? this.config.i18n.defaultLocale;
|
|
1001
1152
|
const headers = convertFastifyHeadersToStandard(request.headers);
|
|
1002
|
-
const session = await this.
|
|
1153
|
+
const session = await this.authValue?.api.getSession({ headers }) ?? null;
|
|
1003
1154
|
const defaultContext = {
|
|
1004
1155
|
transport: "ws",
|
|
1005
1156
|
request,
|
|
@@ -1012,15 +1163,12 @@ var init_sonamu = __esmMin((() => {
|
|
|
1012
1163
|
};
|
|
1013
1164
|
if (config.websocketContextProvider) return { ...await Promise.resolve(config.websocketContextProvider(defaultContext, request)) };
|
|
1014
1165
|
const replyStub = createWebSocketReplyStub();
|
|
1015
|
-
const createSSE = (_events) => {
|
|
1016
|
-
throw new Error("createSSE is not available in websocket context. Define websocketContextProvider if your context setup depends on SSE helpers.");
|
|
1017
|
-
};
|
|
1018
1166
|
const { transport: _transport, reply: _reply, createSSE: _createSSE, bufferedFiles: _bufferedFiles, uploadedFiles: _uploadedFiles, ...rest } = await Promise.resolve(config.contextProvider({
|
|
1019
1167
|
transport: "http",
|
|
1020
1168
|
request,
|
|
1021
1169
|
reply: replyStub,
|
|
1022
1170
|
headers: request.headers,
|
|
1023
|
-
createSSE,
|
|
1171
|
+
createSSE: createUnavailableSSE,
|
|
1024
1172
|
naiteStore: defaultContext.naiteStore,
|
|
1025
1173
|
locale,
|
|
1026
1174
|
user: defaultContext.user,
|
|
@@ -1152,12 +1300,9 @@ var init_sonamu = __esmMin((() => {
|
|
|
1152
1300
|
});
|
|
1153
1301
|
}
|
|
1154
1302
|
async printStartupSummary() {
|
|
1155
|
-
const chalk = (await import("chalk")).default;
|
|
1156
1303
|
const activePreset = getSonamuEnvironment();
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
dim(`Config loaded${formatTime(this._configElapsed)}`);
|
|
1160
|
-
green("DB");
|
|
1304
|
+
printDimSummary(`Config loaded${formatTime(this.configElapsed)}`);
|
|
1305
|
+
printGreenSummary("DB");
|
|
1161
1306
|
const { isLocal } = await import("../utils/controller.js");
|
|
1162
1307
|
const presetNames = Object.keys(this.dbConfig);
|
|
1163
1308
|
const maxLen = Math.max(...presetNames.map((n) => n.length));
|
|
@@ -1170,16 +1315,16 @@ var init_sonamu = __esmMin((() => {
|
|
|
1170
1315
|
if (name === activePreset) console.log(chalk.green(` \u25b8 ${padded} ${addr}`) + remoteTag);
|
|
1171
1316
|
else console.log(chalk.dim(` ${padded} ${addr}`) + remoteTag);
|
|
1172
1317
|
}
|
|
1173
|
-
if (this.config.server.auth)
|
|
1174
|
-
if (this.config.api.timezone)
|
|
1175
|
-
|
|
1318
|
+
if (this.config.server.auth) printDimSummary(`Auth: better-auth at ${this.config.server.auth.basePath ?? "/api/auth"}/*`);
|
|
1319
|
+
if (this.config.api.timezone) printDimSummary(`Timezone: ${this.config.api.timezone}`);
|
|
1320
|
+
printGreenSummary(`Sonamu ready${formatTime(this.initElapsed)}`);
|
|
1176
1321
|
}
|
|
1177
1322
|
async initializeCache(config, forTesting) {
|
|
1178
1323
|
const { setCacheManagerRef } = await import("../cache/decorator.js");
|
|
1179
1324
|
if (forTesting) {
|
|
1180
1325
|
const { createTestCacheManager } = await import("../cache/cache-manager.js");
|
|
1181
|
-
this.
|
|
1182
|
-
setCacheManagerRef(this.
|
|
1326
|
+
this.cacheValue = createTestCacheManager();
|
|
1327
|
+
setCacheManagerRef(this.cacheValue);
|
|
1183
1328
|
return;
|
|
1184
1329
|
}
|
|
1185
1330
|
if (!config) {
|
|
@@ -1187,12 +1332,12 @@ var init_sonamu = __esmMin((() => {
|
|
|
1187
1332
|
return;
|
|
1188
1333
|
}
|
|
1189
1334
|
const { createCacheManager } = await import("../cache/cache-manager.js");
|
|
1190
|
-
this.
|
|
1191
|
-
setCacheManagerRef(this.
|
|
1335
|
+
this.cacheValue = createCacheManager(config);
|
|
1336
|
+
setCacheManagerRef(this.cacheValue);
|
|
1192
1337
|
}
|
|
1193
1338
|
async initializeWorkflows(options) {
|
|
1194
1339
|
const { WorkflowManager } = await import("../tasks/workflow-manager.js");
|
|
1195
|
-
this.
|
|
1340
|
+
this.workflowsValue = new WorkflowManager(DB.getDBConfig("w"));
|
|
1196
1341
|
if (!options) return;
|
|
1197
1342
|
const enableWorker = options.enableWorker ?? isDaemonServer();
|
|
1198
1343
|
const defaultWorkerOptions = {
|
|
@@ -1232,7 +1377,6 @@ var init_sonamu = __esmMin((() => {
|
|
|
1232
1377
|
await this.workflows.startWorker();
|
|
1233
1378
|
await options.lifecycle?.onStart?.(server);
|
|
1234
1379
|
}).catch(async (err) => {
|
|
1235
|
-
const chalk = (await import("chalk")).default;
|
|
1236
1380
|
console.error(chalk.red("Failed to start server:", err));
|
|
1237
1381
|
await shutdown();
|
|
1238
1382
|
});
|
|
@@ -1240,12 +1384,12 @@ var init_sonamu = __esmMin((() => {
|
|
|
1240
1384
|
async destroy() {
|
|
1241
1385
|
const { BaseModel } = await import("../database/base-model.js");
|
|
1242
1386
|
await BaseModel.destroy();
|
|
1243
|
-
if (this.
|
|
1244
|
-
this.
|
|
1387
|
+
if (this.websocketRuntimeValue) await this.websocketRuntimeValue.shutdown();
|
|
1388
|
+
this.websocketRuntimeValue = null;
|
|
1245
1389
|
await Promise.allSettled([
|
|
1246
|
-
this.
|
|
1247
|
-
this.
|
|
1248
|
-
this.
|
|
1390
|
+
this.workflowsValue?.destroy() ?? Promise.resolve(),
|
|
1391
|
+
this.cacheValue?.disconnect() ?? Promise.resolve(),
|
|
1392
|
+
this.devVitestManagerValue?.shutdown() ?? Promise.resolve(),
|
|
1249
1393
|
this.watcher?.close() ?? Promise.resolve()
|
|
1250
1394
|
]);
|
|
1251
1395
|
await dispose();
|
|
@@ -1261,6 +1405,6 @@ var init_sonamu = __esmMin((() => {
|
|
|
1261
1405
|
}));
|
|
1262
1406
|
//#endregion
|
|
1263
1407
|
init_sonamu();
|
|
1264
|
-
export { Sonamu, createWebSocketReplyStub, init_sonamu, resolveWebSocketCloseDescriptor, resolveWebSocketPluginOptions };
|
|
1408
|
+
export { Sonamu, createWebSocketReplyStub, defaultSonamuHttpValidatorDependencies, init_sonamu, resolveWebSocketCloseDescriptor, resolveWebSocketPluginOptions };
|
|
1265
1409
|
|
|
1266
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic29uYW11LmpzIiwibmFtZXMiOlsibWltZUxvb2t1cCIsImxvZ3RhcGVEaXNwb3NlIl0sInNvdXJjZXMiOlsiLi4vLi4vc3JjL2FwaS9zb25hbXUudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQXN5bmNMb2NhbFN0b3JhZ2UgfSBmcm9tIFwiYXN5bmNfaG9va3NcIjtcbmltcG9ydCBmcyBmcm9tIFwiZnMvcHJvbWlzZXNcIjtcbmltcG9ydCB7IHR5cGUgSW5jb21pbmdNZXNzYWdlLCB0eXBlIFNlcnZlciwgdHlwZSBTZXJ2ZXJSZXNwb25zZSB9IGZyb20gXCJodHRwXCI7XG5pbXBvcnQgb3MgZnJvbSBcIm9zXCI7XG5pbXBvcnQgcGF0aCBmcm9tIFwicGF0aFwiO1xuXG5pbXBvcnQgdHlwZSB7fSBmcm9tIFwiQGZhc3RpZnkvd2Vic29ja2V0XCI7XG5pbXBvcnQgeyBkaXNwb3NlIGFzIGxvZ3RhcGVEaXNwb3NlIH0gZnJvbSBcIkBsb2d0YXBlL2xvZ3RhcGVcIjtcbmltcG9ydCB7IHR5cGUgQXV0aCwgdHlwZSBCZXR0ZXJBdXRoT3B0aW9ucyB9IGZyb20gXCJiZXR0ZXItYXV0aFwiO1xuaW1wb3J0IGNoYWxrIGZyb20gXCJjaGFsa1wiO1xuaW1wb3J0IHsgdHlwZSBGU1dhdGNoZXIgfSBmcm9tIFwiY2hva2lkYXJcIjtcbmltcG9ydCB7IHR5cGUgRmFzdGlmeUluc3RhbmNlLCB0eXBlIEZhc3RpZnlSZXBseSwgdHlwZSBGYXN0aWZ5UmVxdWVzdCB9IGZyb20gXCJmYXN0aWZ5XCI7XG5pbXBvcnQgbWltZSwgeyBsb29rdXAgYXMgbWltZUxvb2t1cCB9IGZyb20gXCJtaW1lLXR5cGVzXCI7XG5pbXBvcnQgeyB0eXBlIFdlYlNvY2tldCB9IGZyb20gXCJ3c1wiO1xuaW1wb3J0IHsgdHlwZSBab2RPYmplY3QgfSBmcm9tIFwiem9kXCI7XG5cbmltcG9ydCB7IEJBU0VfRklFTERfTUFQUElOR1MgfSBmcm9tIFwiLi4vYXV0aC9iZXR0ZXItYXV0aC1lbnRpdGllc1wiO1xuaW1wb3J0IHsgY3JlYXRlQmV0dGVyQXV0aFJlcXVlc3QgfSBmcm9tIFwiLi4vYXV0aC9iZXR0ZXItYXV0aC1yZXF1ZXN0XCI7XG5pbXBvcnQgeyBhcHBseUNhY2hlSGVhZGVycywgQ2FjaGVQcmVzZXRzIH0gZnJvbSBcIi4uL2NhY2hlLWNvbnRyb2wvY2FjaGUtY29udHJvbFwiO1xuaW1wb3J0IHsgdHlwZSBDYWNoZUNvbnRyb2xDb25maWcsIHR5cGUgQ2FjaGVDb250cm9sUmVxdWVzdCB9IGZyb20gXCIuLi9jYWNoZS1jb250cm9sL3R5cGVzXCI7XG5pbXBvcnQgeyB0eXBlIENhY2hlQ29uZmlnLCB0eXBlIENhY2hlTWFuYWdlciB9IGZyb20gXCIuLi9jYWNoZS90eXBlc1wiO1xuaW1wb3J0IHsgdG9GYXN0aWZ5Q29tcHJlc3NPcHRpb24gfSBmcm9tIFwiLi4vY29tcHJlc3MvY29tcHJlc3NcIjtcbmltcG9ydCB7IHR5cGUgQ29tcHJlc3NPcHRpb25zIH0gZnJvbSBcIi4uL2NvbXByZXNzL3R5cGVzXCI7XG5pbXBvcnQgeyBEQiB9IGZyb20gXCIuLi9kYXRhYmFzZS9kYlwiO1xuaW1wb3J0IHsgdHlwZSBTb25hbXVEQkNvbmZpZyB9IGZyb20gXCIuLi9kYXRhYmFzZS9kYlwiO1xuaW1wb3J0IHsgU0QsIHNldFNEQ29uZmlnIH0gZnJvbSBcIi4uL2RpY3Qvc2RcIjtcbmltcG9ydCB7IHR5cGUgTG9jYWxpemVkU3RyaW5nIH0gZnJvbSBcIi4uL2RpY3QvdHlwZXNcIjtcbmltcG9ydCB7IGdldFNvbmFtdUVudmlyb25tZW50LCByZWFkQWxsRW52aXJvbm1lbnRTbmFwc2hvdHMgfSBmcm9tIFwiLi4vZW52XCI7XG5pbXBvcnQgeyBOb3RGb3VuZEV4Y2VwdGlvbiB9IGZyb20gXCIuLi9leGNlcHRpb25zL3NvLWV4Y2VwdGlvbnNcIjtcbmltcG9ydCB7IEJ1ZmZlcmVkRmlsZSB9IGZyb20gXCIuLi9zdG9yYWdlL2J1ZmZlcmVkLWZpbGVcIjtcbmltcG9ydCB7IHR5cGUgU3RvcmFnZU1hbmFnZXIgfSBmcm9tIFwiLi4vc3RvcmFnZS9zdG9yYWdlLW1hbmFnZXJcIjtcbmltcG9ydCB7IHR5cGUgS2V5R2VuZXJhdG9yIH0gZnJvbSBcIi4uL3N0b3JhZ2UvdHlwZXNcIjtcbmltcG9ydCB7IFVwbG9hZGVkRmlsZSB9IGZyb20gXCIuLi9zdG9yYWdlL3VwbG9hZGVkLWZpbGVcIjtcbmltcG9ydCB7IGNyZWF0ZU1vY2tTU0VGYWN0b3J5IH0gZnJvbSBcIi4uL3N0cmVhbS9zc2VcIjtcbmltcG9ydCB7IFdlYlNvY2tldFJ1bnRpbWUsIHR5cGUgV2ViU29ja2V0Q29ubmVjdGlvbiwgdHlwZSBXZWJTb2NrZXRFdmVudE1hcCB9IGZyb20gXCIuLi9zdHJlYW0vd3NcIjtcbmltcG9ydCB7XG4gIHR5cGUgVGVsZW1ldHJ5Q29udGV4dFByb3ZpZGVyLFxuICB0eXBlIFdlYlNvY2tldFRlbGVtZXRyeUNvbm5lY3Rpb25Db250ZXh0LFxufSBmcm9tIFwiLi4vc3RyZWFtL3dzLXRlbGVtZXRyeVwiO1xuaW1wb3J0IHsgdHlwZSBTeW5jZXIgfSBmcm9tIFwiLi4vc3luY2VyL3N5bmNlclwiO1xuaW1wb3J0IHsgdHlwZSBXb3JrZmxvd01hbmFnZXIgfSBmcm9tIFwiLi4vdGFza3Mvd29ya2Zsb3ctbWFuYWdlclwiO1xuaW1wb3J0IHsgdHlwZSBEZXZWaXRlc3RNYW5hZ2VyIH0gZnJvbSBcIi4uL3Rlc3RpbmcvZGV2LXZpdGVzdC1tYW5hZ2VyXCI7XG5pbXBvcnQgeyB0eXBlIFNvbmFtdUZhc3RpZnlDb25maWcgfSBmcm9tIFwiLi4vdHlwZXMvdHlwZXNcIjtcbmltcG9ydCB7IGNlbnRlclRleHQgfSBmcm9tIFwiLi4vdXRpbHMvY29uc29sZS11dGlsXCI7XG5pbXBvcnQgeyBpc0RhZW1vblNlcnZlciB9IGZyb20gXCIuLi91dGlscy9jb250cm9sbGVyXCI7XG5pbXBvcnQgeyBleGlzdHMsIGZpbGVFeGlzdHMgfSBmcm9tIFwiLi4vdXRpbHMvZnMtdXRpbHNcIjtcbmltcG9ydCB7IHR5cGUgQWJzb2x1dGVQYXRoIH0gZnJvbSBcIi4uL3V0aWxzL3BhdGgtdXRpbHNcIjtcbmltcG9ydCB7IGNvbnZlcnRGYXN0aWZ5SGVhZGVyc1RvU3RhbmRhcmQsIG1lcmdlIH0gZnJvbSBcIi4uL3V0aWxzL3V0aWxzXCI7XG5pbXBvcnQgeyB0eXBlIFNvbmFtdUNvbmZpZywgdHlwZSBTb25hbXVTZXJ2ZXJPcHRpb25zLCB0eXBlIFNvbmFtdVRhc2tPcHRpb25zIH0gZnJvbSBcIi4vY29uZmlnXCI7XG5pbXBvcnQgeyB0eXBlIENvbnRleHQsIHR5cGUgUnVudGltZUNvbnRleHQsIHR5cGUgV2ViU29ja2V0Q29udGV4dCB9IGZyb20gXCIuL2NvbnRleHRcIjtcbmltcG9ydCB7IHR5cGUgRXh0ZW5kZWRBcGkgfSBmcm9tIFwiLi9kZWNvcmF0b3JzXCI7XG5pbXBvcnQgeyBnZXRTZWNyZXRzIH0gZnJvbSBcIi4vc2VjcmV0XCI7XG5pbXBvcnQgeyB0eXBlIFNvbmFtdVNlY3JldHMgfSBmcm9tIFwiLi9zZWNyZXRcIjtcbmltcG9ydCB7XG4gIGNyZWF0ZVdlYlNvY2tldFJlcGx5U3R1YixcbiAgcmVzb2x2ZVdlYlNvY2tldENsb3NlRGVzY3JpcHRvcixcbiAgcmVzb2x2ZVdlYlNvY2tldFBsdWdpbk9wdGlvbnMsXG4gIHJlc29sdmVJbnRlZ3JhdGVkVml0ZUhtck9wdGlvbnMsXG59IGZyb20gXCIuL3dlYnNvY2tldC1oZWxwZXJzXCI7XG5cbmV4cG9ydCB7XG4gIGNyZWF0ZVdlYlNvY2tldFJlcGx5U3R1YixcbiAgcmVzb2x2ZVdlYlNvY2tldENsb3NlRGVzY3JpcHRvcixcbiAgcmVzb2x2ZVdlYlNvY2tldFBsdWdpbk9wdGlvbnMsXG59IGZyb20gXCIuL3dlYnNvY2tldC1oZWxwZXJzXCI7XG5cbmNsYXNzIFNvbmFtdUNsYXNzIHtcbiAgcHVibGljIGlzSW5pdGlhbGl6ZWQ6IGJvb2xlYW4gPSBmYWxzZTtcbiAgcHVibGljIGZvclRlc3Rpbmc6IGJvb2xlYW4gPSBmYWxzZTtcbiAgcHVibGljIGFzeW5jTG9jYWxTdG9yYWdlOiBBc3luY0xvY2FsU3RvcmFnZTx7XG4gICAgY29udGV4dDogUnVudGltZUNvbnRleHQ7XG4gIH0+ID0gbmV3IEFzeW5jTG9jYWxTdG9yYWdlKCk7XG5cbiAgcHVibGljIGdldENvbnRleHQ8VCBleHRlbmRzIFJ1bnRpbWVDb250ZXh0ID0gQ29udGV4dD4oKTogVCB7XG4gICAgY29uc3Qgc3RvcmUgPSB0aGlzLmFzeW5jTG9jYWxTdG9yYWdlLmdldFN0b3JlKCk7XG4gICAgaWYgKHN0b3JlPy5jb250ZXh0KSB7XG4gICAgICByZXR1cm4gc3RvcmUuY29udGV4dCBhcyBUO1xuICAgIH1cblxuICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViA9PT0gXCJ0ZXN0XCIpIHtcbiAgICAgIC8vIO2FjOyKpO2MhSDtmZjqsr3sl5DshJwg7Luo7YWN7Iqk7Yq46rCAIOyjvOyeheuQmOyngCDslYrsnYAg6rK97JqwIOu5iCDsu6jthY3siqTtirgg66as7YS0XG4gICAgICByZXR1cm4ge1xuICAgICAgICB0cmFuc3BvcnQ6IFwiaHR0cFwiLFxuICAgICAgICByZXF1ZXN0OiBudWxsLFxuICAgICAgICByZXBseTogbnVsbCxcbiAgICAgICAgaGVhZGVyczoge30sXG4gICAgICAgIGNyZWF0ZVNTRTogKHNjaGVtYTogWm9kT2JqZWN0KSA9PiBjcmVhdGVNb2NrU1NFRmFjdG9yeShzY2hlbWEpLFxuICAgICAgICBsb2NhbGU6IFwiXCIsXG4gICAgICAgIHVzZXI6IG51bGwsXG4gICAgICAgIHNlc3Npb246IG51bGwsXG4gICAgICAgIG5haXRlU3RvcmU6IG5ldyBNYXA8c3RyaW5nLCBhbnk+KCksXG4gICAgICB9IGFzIHVua25vd24gYXMgVDtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiU29uYW11IGNhbm5vdCBmaW5kIGNvbnRleHRcIik7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBfYXBpUm9vdFBhdGg6IEFic29sdXRlUGF0aCB8IG51bGwgPSBudWxsO1xuICBzZXQgYXBpUm9vdFBhdGgoYXBpUm9vdFBhdGg6IEFic29sdXRlUGF0aCkge1xuICAgIHRoaXMuX2FwaVJvb3RQYXRoID0gYXBpUm9vdFBhdGg7XG4gIH1cbiAgZ2V0IGFwaVJvb3RQYXRoKCk6IEFic29sdXRlUGF0aCB7XG4gICAgaWYgKHRoaXMuX2FwaVJvb3RQYXRoID09PSBudWxsKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJTb25hbXUgaGFzIG5vdCBiZWVuIGluaXRpYWxpemVkXCIpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fYXBpUm9vdFBhdGg7XG4gIH1cbiAgZ2V0IGFwcFJvb3RQYXRoKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuYXBpUm9vdFBhdGguc3BsaXQocGF0aC5zZXApLnNsaWNlKDAsIC0xKS5qb2luKHBhdGguc2VwKTtcbiAgfVxuXG4gIHByaXZhdGUgX2RiQ29uZmlnOiBTb25hbXVEQkNvbmZpZyB8IG51bGwgPSBudWxsO1xuICBzZXQgZGJDb25maWcoZGJDb25maWc6IFNvbmFtdURCQ29uZmlnKSB7XG4gICAgdGhpcy5fZGJDb25maWcgPSBkYkNvbmZpZztcbiAgfVxuICBnZXQgZGJDb25maWcoKTogU29uYW11REJDb25maWcge1xuICAgIGlmICh0aGlzLl9kYkNvbmZpZyA9PT0gbnVsbCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiU29uYW11IGhhcyBub3QgYmVlbiBpbml0aWFsaXplZFwiKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX2RiQ29uZmlnO1xuICB9XG5cbiAgcHJpdmF0ZSBfc3luY2VyOiBTeW5jZXIgfCBudWxsID0gbnVsbDtcbiAgc2V0IHN5bmNlcihzeW5jZXI6IFN5bmNlcikge1xuICAgIHRoaXMuX3N5bmNlciA9IHN5bmNlcjtcbiAgfVxuICBnZXQgc3luY2VyKCk6IFN5bmNlciB7XG4gICAgaWYgKHRoaXMuX3N5bmNlciA9PT0gbnVsbCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiU29uYW11IGhhcyBub3QgYmVlbiBpbml0aWFsaXplZFwiKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX3N5bmNlcjtcbiAgfVxuXG4gIHByaXZhdGUgX2NvbmZpZzogU29uYW11Q29uZmlnIHwgbnVsbCA9IG51bGw7XG4gIHNldCBjb25maWcoY29uZmlnOiBTb25hbXVDb25maWcpIHtcbiAgICB0aGlzLl9jb25maWcgPSBjb25maWc7XG4gIH1cbiAgZ2V0IGNvbmZpZygpOiBTb25hbXVDb25maWcge1xuICAgIGlmICh0aGlzLl9jb25maWcgPT09IG51bGwpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlNvbmFtdSBoYXMgbm90IGJlZW4gaW5pdGlhbGl6ZWRcIik7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLl9jb25maWc7XG4gIH1cblxuICBwdWJsaWMgcmVhZG9ubHkgc2VjcmV0czogU29uYW11U2VjcmV0cyA9IGdldFNlY3JldHMoKTtcblxuICBwcml2YXRlIF9zdG9yYWdlOiBTdG9yYWdlTWFuYWdlciB8IG51bGwgPSBudWxsO1xuICAvKipcbiAgICogU3RvcmFnZU1hbmFnZXIg7J247Iqk7YS07IqkXG4gICAqL1xuICBnZXQgc3RvcmFnZSgpOiBTdG9yYWdlTWFuYWdlciB7XG4gICAgaWYgKCF0aGlzLl9zdG9yYWdlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJTdG9yYWdlIGhhcyBub3QgYmVlbiBpbml0aWFsaXplZC4gQ2hlY2sgc3RvcmFnZSBjb25maWcuXCIpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fc3RvcmFnZTtcbiAgfVxuXG4gIHByaXZhdGUgX2NhY2hlOiBDYWNoZU1hbmFnZXIgfCBudWxsID0gbnVsbDtcbiAgLyoqXG4gICAqIENhY2hlTWFuYWdlciDsnbjsiqTthLTsiqQgKEJlbnRvQ2FjaGUpXG4gICAqL1xuICBnZXQgY2FjaGUoKTogQ2FjaGVNYW5hZ2VyIHtcbiAgICBpZiAoIXRoaXMuX2NhY2hlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJDYWNoZSBoYXMgbm90IGJlZW4gaW5pdGlhbGl6ZWQuIENoZWNrIGNhY2hlIGNvbmZpZyBpbiBzb25hbXUuY29uZmlnLnRzLlwiKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX2NhY2hlO1xuICB9XG5cbiAgcHJpdmF0ZSBfd29ya2Zsb3dzOiBXb3JrZmxvd01hbmFnZXIgfCBudWxsID0gbnVsbDtcbiAgZ2V0IHdvcmtmbG93cygpOiBXb3JrZmxvd01hbmFnZXIge1xuICAgIGlmICh0aGlzLl93b3JrZmxvd3MgPT09IG51bGwpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlNvbmFtdSBoYXMgbm90IGJlZW4gaW5pdGlhbGl6ZWRcIik7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuX3dvcmtmbG93cztcbiAgfVxuXG4gIHByaXZhdGUgX2F1dGg6IEF1dGg8QmV0dGVyQXV0aE9wdGlvbnM+IHwgbnVsbCA9IG51bGw7XG4gIGdldCBhdXRoKCk6IEF1dGg8QmV0dGVyQXV0aE9wdGlvbnM+IHtcbiAgICBpZiAoIXRoaXMuX2F1dGgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkF1dGggaGFzIG5vdCBiZWVuIGluaXRpYWxpemVkLiBDaGVjayBhdXRoIGNvbmZpZyBpbiBzb25hbXUuY29uZmlnLnRzLlwiKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX2F1dGg7XG4gIH1cblxuICBwcml2YXRlIF9kZXZWaXRlc3RNYW5hZ2VyOiBEZXZWaXRlc3RNYW5hZ2VyIHwgbnVsbCA9IG51bGw7XG4gIGdldCBkZXZWaXRlc3RNYW5hZ2VyKCk6IERldlZpdGVzdE1hbmFnZXIgfCBudWxsIHtcbiAgICByZXR1cm4gdGhpcy5fZGV2Vml0ZXN0TWFuYWdlcjtcbiAgfVxuICBzZXQgZGV2Vml0ZXN0TWFuYWdlcihtYW5hZ2VyOiBEZXZWaXRlc3RNYW5hZ2VyIHwgbnVsbCkge1xuICAgIHRoaXMuX2RldlZpdGVzdE1hbmFnZXIgPSBtYW5hZ2VyO1xuICB9XG5cbiAgLy8gU29uYW116rCAIHJ1bnRpbWXsnYQg7KeB7KCRIOyGjOycoO2VtCByZWdpc3RyeS9jb25uZWN0aW9uIGxpZmVjeWNsZeydhCDslaDtlIzrpqzsvIDsnbTshZgg7IiY66qF7KO86riw7JmAIOuPmeq4sO2ZlO2VqFxuICBwcml2YXRlIF93ZWJzb2NrZXRSdW50aW1lOiBXZWJTb2NrZXRSdW50aW1lIHwgbnVsbCA9IG51bGw7XG4gIC8vIOqwmeydgCBGYXN0aWZ5IOyduOyKpO2EtOyKpOyXkCBAZmFzdGlmeS93ZWJzb2NrZXTsnYQg7KSR67O1IOuTseuhne2VmOuKlCDqsoPsnYQgV2Vha1NldOycvOuhnCDssKjri6jtlahcbiAgcHJpdmF0ZSByZWFkb25seSB3ZWJzb2NrZXRQbHVnaW5TZXJ2ZXJzID0gbmV3IFdlYWtTZXQ8XG4gICAgRmFzdGlmeUluc3RhbmNlPFNlcnZlciwgSW5jb21pbmdNZXNzYWdlLCBTZXJ2ZXJSZXNwb25zZT5cbiAgPigpO1xuICBnZXQgd2Vic29ja2V0UnVudGltZSgpOiBXZWJTb2NrZXRSdW50aW1lIHtcbiAgICBpZiAoIXRoaXMuX3dlYnNvY2tldFJ1bnRpbWUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIldlYlNvY2tldCBydW50aW1lIGhhcyBub3QgYmVlbiBpbml0aWFsaXplZC5cIik7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLl93ZWJzb2NrZXRSdW50aW1lO1xuICB9XG4gIHNldCB3ZWJzb2NrZXRSdW50aW1lKHJ1bnRpbWU6IFdlYlNvY2tldFJ1bnRpbWUgfCBudWxsKSB7XG4gICAgdGhpcy5fd2Vic29ja2V0UnVudGltZSA9IHJ1bnRpbWU7XG4gIH1cblxuICAvLyBITVIg7LKY66asOiDtjIzsnbwg7Iuc7Iqk7YWcIOqwkOyLnCArIEhNUi9zeW5jIOyCrOydtO2BtCDsi6TtlonsnYAgd2F0Y2hlciDrqqjrk4jroZwg7JyE7J6E7ZWp64uI64ukLlxuICBwdWJsaWMgd2F0Y2hlcjogRlNXYXRjaGVyIHwgbnVsbCA9IG51bGw7XG5cbiAgcHVibGljIHNlcnZlcjogRmFzdGlmeUluc3RhbmNlIHwgbnVsbCA9IG51bGw7XG5cbiAgYXN5bmMgaW5pdEZvclRlc3RpbmcoKSB7XG4gICAgYXdhaXQgdGhpcy5pbml0KHRydWUsIGZhbHNlLCB1bmRlZmluZWQsIHRydWUpO1xuICB9XG5cbiAgYXN5bmMgaW5pdChcbiAgICBkb1NpbGVudDogYm9vbGVhbiA9IGZhbHNlLFxuICAgIGVuYWJsZVN5bmM6IGJvb2xlYW4gPSB0cnVlLFxuICAgIGFwaVJvb3RQYXRoPzogQWJzb2x1dGVQYXRoLFxuICAgIGZvclRlc3Rpbmc6IGJvb2xlYW4gPSBmYWxzZSxcbiAgKSB7XG4gICAgdGhpcy5mb3JUZXN0aW5nID0gZm9yVGVzdGluZztcblxuICAgIGlmICh0aGlzLmlzSW5pdGlhbGl6ZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBpbml0U3RhcnQgPSBwZXJmb3JtYW5jZS5ub3coKTtcblxuICAgIC8vIEFQSSDro6jtirgg7Yyo7IqkXG4gICAgY29uc3QgeyBmaW5kQXBpUm9vdFBhdGggfSA9IGF3YWl0IGltcG9ydChcIi4uL3V0aWxzL3V0aWxzXCIpO1xuICAgIHRoaXMuYXBpUm9vdFBhdGggPSBhcGlSb290UGF0aCA/PyBmaW5kQXBpUm9vdFBhdGgoKTtcbiAgICBjb25zdCBiYXNlRW52QmVmb3JlQ29uZmlnTG9hZCA9IHsgLi4ucHJvY2Vzcy5lbnYgfTtcblxuICAgIC8vIOyEpOygleydhCDroZzrlKntlZjripQg6rKD67aA7YSwIOyLnOyekVxuICAgIGNvbnN0IGNvbmZpZ1N0YXJ0ID0gcGVyZm9ybWFuY2Uubm93KCk7XG4gICAgY29uc3QgeyBsb2FkQ29uZmlnIH0gPSBhd2FpdCBpbXBvcnQoXCIuL2NvbmZpZ1wiKTtcbiAgICB0aGlzLmNvbmZpZyA9IGF3YWl0IGxvYWRDb25maWcodGhpcy5hcGlSb290UGF0aCk7XG4gICAgY29uc3QgY29uZmlnVGltZSA9IHBlcmZvcm1hbmNlLm5vdygpIC0gY29uZmlnU3RhcnQ7XG4gICAgc2V0U0RDb25maWcodGhpcy5jb25maWcuaTE4bik7XG4gICAgLy8gc29uYW11LmNvbmZpZy50cyDquLDrs7jqsJIg7ISk7KCVXG4gICAgdGhpcy5jb25maWcuZGF0YWJhc2UuZGF0YWJhc2UgPSB0aGlzLmNvbmZpZy5kYXRhYmFzZS5kYXRhYmFzZSA/PyBcInBnXCI7XG4gICAgdGhpcy5jb25maWcuZGF0YWJhc2UuZGVmYXVsdE9wdGlvbnMgPSB0aGlzLmNvbmZpZy5kYXRhYmFzZS5kZWZhdWx0T3B0aW9ucyA/PyB7fTtcbiAgICB0aGlzLmNvbmZpZy5kYXRhYmFzZS5kZWZhdWx0T3B0aW9ucy5jbGllbnQgPSB0aGlzLmNvbmZpZy5kYXRhYmFzZS5kYXRhYmFzZSA/PyBcInBnXCI7XG5cbiAgICAvLyDroZzquYUg7ISk7KCVXG4gICAgY29uc3QgeyBjb25maWd1cmVMb2dUYXBlIH0gPSBhd2FpdCBpbXBvcnQoXCIuLi9sb2dnZXIvY29uZmlndXJlXCIpO1xuICAgIGlmICh0aGlzLmNvbmZpZy5sb2dnaW5nICE9PSBmYWxzZSkge1xuICAgICAgYXdhaXQgY29uZmlndXJlTG9nVGFwZSh7XG4gICAgICAgIC4uLnRoaXMuY29uZmlnLmxvZ2dpbmcsXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvLyBEQiDroZzrk5xcbiAgICBjb25zdCB7IERCIH0gPSBhd2FpdCBpbXBvcnQoXCIuLi9kYXRhYmFzZS9kYlwiKTtcbiAgICBjb25zdCB7IGlzTG9jYWw6IGlzTG9jYWxFbnZpcm9ubWVudCB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vdXRpbHMvY29udHJvbGxlclwiKTtcbiAgICBjb25zdCBlbnZpcm9ubWVudFNuYXBzaG90cyA9IGlzTG9jYWxFbnZpcm9ubWVudCgpXG4gICAgICA/IHJlYWRBbGxFbnZpcm9ubWVudFNuYXBzaG90cyh0aGlzLmFwaVJvb3RQYXRoLCBiYXNlRW52QmVmb3JlQ29uZmlnTG9hZClcbiAgICAgIDogdW5kZWZpbmVkO1xuICAgIHRoaXMuZGJDb25maWcgPSBEQi5nZW5lcmF0ZURCQ29uZmlnKFxuICAgICAgdGhpcy5jb25maWcuZGF0YWJhc2UsXG4gICAgICB0aGlzLmNvbmZpZy5wcm9qZWN0TmFtZSxcbiAgICAgIGVudmlyb25tZW50U25hcHNob3RzLFxuICAgICk7XG4gICAgREIuc2V0Q29uZmlnKHRoaXMuZGJDb25maWcpO1xuXG4gICAgLy8gRW50aXR5IOuhnOuTnFxuICAgIC8vIO2FjOyKpO2KuOyXkOyEnOuPhCBFbnRpdHkg7KCV67O064qUIO2VhOyalO2VqeuLiOuLpC5cbiAgICAvLyB1cHNlcnTqsIAg7KCc64yA66GcIOyekeuPme2VmOugpOuptCBlbnRpdHnsnZggdW5pcXVlIGluZGV4IOygleuztOqwgCDtlYTsmpTtlZjquLAg65WM66y47J6F64uI64ukLlxuICAgIGNvbnN0IHsgRW50aXR5TWFuYWdlciB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vZW50aXR5L2VudGl0eS1tYW5hZ2VyXCIpO1xuICAgIGF3YWl0IEVudGl0eU1hbmFnZXIuYXV0b2xvYWQoZG9TaWxlbnQpO1xuXG4gICAgLy8gQ2FjaGUg7LSI6riw7ZmUXG4gICAgYXdhaXQgdGhpcy5pbml0aWFsaXplQ2FjaGUodGhpcy5jb25maWcuc2VydmVyLmNhY2hlLCBmb3JUZXN0aW5nKTtcblxuICAgIC8vIEJldHRlckF1dGgg7LSI6riw7ZmUXG4gICAgY29uc3QgYXV0aENvbmZpZyA9IHRoaXMuY29uZmlnLnNlcnZlci5hdXRoO1xuICAgIGlmIChhdXRoQ29uZmlnKSB7XG4gICAgICAvLyDsgqzsmqnsnpAg7ISk7KCV6rO8IOq4sOuzuOqwkuydhCBtZXJnZVxuICAgICAgY29uc3QgbWVyZ2VkRmllbGRNYXBwaW5ncyA9IG1lcmdlKEJBU0VfRklFTERfTUFQUElOR1MsIGF1dGhDb25maWcpO1xuXG4gICAgICAvLyBiZXR0ZXItYXV0aCDsnbjsiqTthLTsiqQg7IOd7ISxXG4gICAgICBjb25zdCB7IGJldHRlckF1dGggfSA9IGF3YWl0IGltcG9ydChcImJldHRlci1hdXRoXCIpO1xuICAgICAgY29uc3QgeyBzb25hbXVLbmV4QWRhcHRlciB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vYXV0aC9rbmV4LWFkYXB0ZXJcIik7XG5cbiAgICAgIGNvbnN0IGF1dGhPcHRpb25zOiBCZXR0ZXJBdXRoT3B0aW9ucyA9IHtcbiAgICAgICAgZGF0YWJhc2U6IHNvbmFtdUtuZXhBZGFwdGVyKCksXG4gICAgICAgIC4uLm1lcmdlZEZpZWxkTWFwcGluZ3MsXG4gICAgICB9O1xuICAgICAgdGhpcy5fYXV0aCA9IGJldHRlckF1dGgoYXV0aE9wdGlvbnMpO1xuICAgIH1cblxuICAgIC8vIO2FjOyKpO2MheyduCDqsr3smrAg7Iux7YGsIOyXhuydtCDspJHri6hcbiAgICBpZiAoZm9yVGVzdGluZykge1xuICAgICAgdGhpcy5pc0luaXRpYWxpemVkID0gdHJ1ZTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBUYXNrIOuTseuhnVxuICAgIGF3YWl0IHRoaXMuaW5pdGlhbGl6ZVdvcmtmbG93cyh0aGlzLmNvbmZpZy50YXNrcyk7XG5cbiAgICAvLyBTeW5jZXJcbiAgICBjb25zdCB7IFN5bmNlciB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vc3luY2VyL3N5bmNlclwiKTtcbiAgICB0aGlzLnN5bmNlciA9IG5ldyBTeW5jZXIoKTtcblxuICAgIC8vIEF1dG9sb2FkOiBNb2RlbHMgLyBUeXBlcyAvIEFQSXMgLyBXb3JrZmxvd3MgLyBUZW1wbGF0ZXMgLyBTU1IgUm91dGVzXG4gICAgYXdhaXQgdGhpcy5zeW5jZXIuYXV0b2xvYWRUeXBlcygpO1xuICAgIGF3YWl0IHRoaXMuc3luY2VyLmF1dG9sb2FkTW9kZWxzKCk7XG4gICAgYXdhaXQgdGhpcy5zeW5jZXIuYXV0b2xvYWRBcGlzKCk7XG4gICAgYXdhaXQgdGhpcy5zeW5jZXIuYXV0b2xvYWRXb3JrZmxvd3MoKTtcbiAgICBjb25zdCB7IFRlbXBsYXRlTWFuYWdlciB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vdGVtcGxhdGVcIik7XG4gICAgYXdhaXQgVGVtcGxhdGVNYW5hZ2VyLmF1dG9sb2FkKCk7XG4gICAgYXdhaXQgdGhpcy5zeW5jZXIuYXV0b2xvYWRTc3JSb3V0ZXMoKTtcblxuICAgIGNvbnN0IHsgaXNMb2NhbCwgaXNUZXN0LCBpc0hvdFJlbG9hZFNlcnZlciB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vdXRpbHMvY29udHJvbGxlclwiKTtcbiAgICBpZiAoaXNMb2NhbCgpICYmICFpc1Rlc3QoKSAmJiBpc0hvdFJlbG9hZFNlcnZlcigpICYmIGVuYWJsZVN5bmMpIHtcbiAgICAgIGF3YWl0IHRoaXMuc3luY2VyLnN5bmMoKTtcbiAgICAgIGF3YWl0IHRoaXMuc3RhcnRXYXRjaGVyKCk7XG4gICAgfVxuXG4gICAgdGhpcy5pc0luaXRpYWxpemVkID0gdHJ1ZTtcbiAgICB0aGlzLl9pbml0RWxhcHNlZCA9IHBlcmZvcm1hbmNlLm5vdygpIC0gaW5pdFN0YXJ0O1xuICAgIHRoaXMuX2NvbmZpZ0VsYXBzZWQgPSBjb25maWdUaW1lO1xuICB9XG5cbiAgcHJpdmF0ZSBfaW5pdEVsYXBzZWQgPSAwO1xuICBwcml2YXRlIF9jb25maWdFbGFwc2VkID0gMDtcblxuICBhc3luYyBjcmVhdGVTZXJ2ZXIoaW5pdE9wdGlvbnM/OiB7IGVuYWJsZVN5bmM/OiBib29sZWFuOyBkb1NpbGVudD86IGJvb2xlYW4gfSkge1xuICAgIGlmICghdGhpcy5pc0luaXRpYWxpemVkKSB7XG4gICAgICBhd2FpdCB0aGlzLmluaXQoaW5pdE9wdGlvbnM/LmRvU2lsZW50LCBpbml0T3B0aW9ucz8uZW5hYmxlU3luYyk7XG4gICAgfVxuXG4gICAgY29uc3Qgb3B0aW9ucyA9IHRoaXMuY29uZmlnLnNlcnZlcjtcbiAgICBjb25zdCB7IGRlZmF1bHQ6IGZhc3RpZnkgfSA9IGF3YWl0IGltcG9ydChcImZhc3RpZnlcIik7XG4gICAgY29uc3QgeyBnZXRMb2dUYXBlRmFzdGlmeUxvZ2dlciB9ID0gYXdhaXQgaW1wb3J0KFwiQGxvZ3RhcGUvZmFzdGlmeVwiKTtcbiAgICBjb25zdCBzZXJ2ZXIgPSBmYXN0aWZ5KHtcbiAgICAgIC4uLm9wdGlvbnMuZmFzdGlmeSxcbiAgICAgIGxvZ2dlcjpcbiAgICAgICAgdGhpcy5jb25maWcubG9nZ2luZyAhPT0gZmFsc2VcbiAgICAgICAgICA/IGdldExvZ1RhcGVGYXN0aWZ5TG9nZ2VyKHtcbiAgICAgICAgICAgICAgY2F0ZWdvcnk6IHRoaXMuY29uZmlnLmxvZ2dpbmc/LmZhc3RpZnlDYXRlZ29yeSA/PyBbXCJmYXN0aWZ5XCJdLFxuICAgICAgICAgICAgfSlcbiAgICAgICAgICA6IHVuZGVmaW5lZCxcbiAgICB9KTtcbiAgICB0aGlzLnNlcnZlciA9IHNlcnZlcjtcbiAgICB0aGlzLndlYnNvY2tldFJ1bnRpbWUgPSBuZXcgV2ViU29ja2V0UnVudGltZShvcHRpb25zLndlYnNvY2tldCk7XG5cbiAgICAvLyBTdG9yYWdlIOyEpOyglSDihpIgU3RvcmFnZU1hbmFnZXIg7IOd7ISxXG4gICAgaWYgKG9wdGlvbnMuc3RvcmFnZSkge1xuICAgICAgY29uc3QgeyBTdG9yYWdlTWFuYWdlciB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vc3RvcmFnZS9zdG9yYWdlLW1hbmFnZXJcIik7XG4gICAgICB0aGlzLl9zdG9yYWdlID0gbmV3IFN0b3JhZ2VNYW5hZ2VyKG9wdGlvbnMuc3RvcmFnZSk7XG4gICAgfVxuXG4gICAgLy8g7ZSM65+s6re47J24IOuTseuhnVxuICAgIGlmIChvcHRpb25zLnBsdWdpbnMpIHtcbiAgICAgIGF3YWl0IHRoaXMucmVnaXN0ZXJQbHVnaW5zKHNlcnZlciwgb3B0aW9ucy5wbHVnaW5zKTtcbiAgICB9XG5cbiAgICBpZiAob3B0aW9ucy5hdXRoKSB7XG4gICAgICBhd2FpdCB0aGlzLnJlZ2lzdGVyQmV0dGVyQXV0aChzZXJ2ZXIsIG9wdGlvbnMuYXV0aCk7XG4gICAgfVxuXG4gICAgLy8gQVBJIOudvOyasO2MhSDshKTsoJVcbiAgICBhd2FpdCB0aGlzLndpdGhGYXN0aWZ5KHNlcnZlciwgb3B0aW9ucy5hcGlDb25maWcsIHtcbiAgICAgIGVuYWJsZVN5bmM6IGluaXRPcHRpb25zPy5lbmFibGVTeW5jLFxuICAgICAgZG9TaWxlbnQ6IGluaXRPcHRpb25zPy5kb1NpbGVudCxcbiAgICB9KTtcblxuICAgIC8vIOyEnOuyhCDsi5zsnpFcbiAgICBhd2FpdCB0aGlzLmJvb3Qoc2VydmVyLCBvcHRpb25zKTtcblxuICAgIGlmICghaW5pdE9wdGlvbnM/LmRvU2lsZW50KSB7XG4gICAgICB0aGlzLnByaW50U3RhcnR1cFN1bW1hcnkoKTtcbiAgICB9XG5cbiAgICByZXR1cm4gc2VydmVyO1xuICB9XG5cbiAgYXN5bmMgd2l0aEZhc3RpZnkoXG4gICAgc2VydmVyOiBGYXN0aWZ5SW5zdGFuY2U8U2VydmVyLCBJbmNvbWluZ01lc3NhZ2UsIFNlcnZlclJlc3BvbnNlPixcbiAgICBjb25maWc6IFNvbmFtdUZhc3RpZnlDb25maWcsXG4gICAgb3B0aW9ucz86IHtcbiAgICAgIGVuYWJsZVN5bmM/OiBib29sZWFuO1xuICAgICAgZG9TaWxlbnQ/OiBib29sZWFuO1xuICAgIH0sXG4gICkge1xuICAgIGlmICghdGhpcy5pc0luaXRpYWxpemVkKSB7XG4gICAgICBhd2FpdCB0aGlzLmluaXQob3B0aW9ucz8uZG9TaWxlbnQsIG9wdGlvbnM/LmVuYWJsZVN5bmMpO1xuICAgIH1cblxuICAgIHRoaXMuc2VydmVyID0gc2VydmVyO1xuICAgIHRoaXMud2Vic29ja2V0UnVudGltZSA/Pz0gbmV3IFdlYlNvY2tldFJ1bnRpbWUodGhpcy5jb25maWcuc2VydmVyLndlYnNvY2tldCk7XG5cbiAgICAvLyB0aW1lem9uZSDshKTsoJVcbiAgICBjb25zdCB0aW1lem9uZSA9IHRoaXMuY29uZmlnLmFwaS50aW1lem9uZTtcbiAgICBpZiAodGltZXpvbmUpIHtcbiAgICAgIC8vIO2DgOyehOyhtOyXkCDrp57qsowg7J2R64u1IOuCoOynnCDsiqTtirjrp4HsnYQg67OA7ZmY7ZW07KO87Ja07JW8IO2VqeuLiOuLpC5cbiAgICAgIC8vIOqwgOuguSB0aW1lem9uZeydtCBcIkFzaWEvU2VvdWxcIiDsnbTrqbRcbiAgICAgIC8vIFwiMjAyNS0xMS0yMVQwMDowMDowMC4wMDBaXCIg66W8IFwiMjAyNS0xMS0yMVQwOTowMDowMCswOTowMFwiIOycvOuhnCDrs4DtmZjtlbTso7zslrTslbwg7ZWp64uI64ukLlxuICAgICAgY29uc3QgeyBmb3JtYXRJblRpbWVab25lIH0gPSBhd2FpdCBpbXBvcnQoXCJkYXRlLWZucy10elwiKTtcblxuICAgICAgLy8gSVNPIDg2MDEg64Kg7KecIO2YleyLnSDsoJXqt5zsi50gKOyYiDogMjAyNC0wMS0xNVQwOTozMDowMC4wMDBaKVxuICAgICAgY29uc3QgSVNPX0RBVEVfUkVHRVggPSAvXlxcZHs0fS1cXGR7Mn0tXFxkezJ9VFxcZHsyfTpcXGR7Mn06XFxkezJ9KFxcLlxcZHszfSk/WiQvO1xuXG4gICAgICAvLyBU66W8IOuRmOufrOyLvCDsnpHsnYDrlLDsmLTtkZzqsIAg7JeG64uk66m0IFwiMjAyNS0xMS0xOTE3NjM1NDYxODkwMDAxODo1NjoyOSswOTowMFwi7JmAIOqwmeydgCDqsrDqs7zqsIAg64KY7Ji164uI64ukLlxuICAgICAgLy8g7J2064qUIGRhdGUtZm5zIO2KueyeheuLiOuLpC5cbiAgICAgIC8vIOydtOugh+qyjCDtlbTrj4Qg6rSc7LCu7Iq164uI64ukLiBcIjIwMjUtMTEtMTlUMTg6NTY6MjkrMDk6MDBcIiDrqqjslpHsnLzroZwg7J6YIOuCmOyYteuLiOuLpC5cbiAgICAgIGNvbnN0IERBVEVfRk9STUFUID0gXCJ5eXl5LU1NLWRkJ1QnSEg6bW06c3NYWFhcIjtcblxuICAgICAgc2VydmVyLnNldFJlcGx5U2VyaWFsaXplcigocGF5bG9hZCkgPT4ge1xuICAgICAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkocGF5bG9hZCwgKF9rZXksIHZhbHVlKSA9PiB7XG4gICAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gXCJzdHJpbmdcIiAmJiBJU09fREFURV9SRUdFWC50ZXN0KHZhbHVlKSkge1xuICAgICAgICAgICAgcmV0dXJuIGZvcm1hdEluVGltZVpvbmUoXG4gICAgICAgICAgICAgIG5ldyBEYXRlKHZhbHVlKSxcbiAgICAgICAgICAgICAgdGltZXpvbmUgYXMgYCR7c3RyaW5nfS8ke3N0cmluZ31gLFxuICAgICAgICAgICAgICBEQVRFX0ZPUk1BVCxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICAgIC8vIFRpbWV6b25lIOuhnOq3uOuKlCBwcmludFN0YXJ0dXBTdW1tYXJ57JeQ7IScIO2Gte2VqSDstpzroKVcbiAgICB9XG5cbiAgICAvLyDsoITssrQg65287Jqw7YyFIOumrOyKpO2KuFxuICAgIHNlcnZlci5nZXQoXG4gICAgICBgJHt0aGlzLmNvbmZpZy5hcGkucm91dGUucHJlZml4fS9yb3V0ZXNgLFxuICAgICAgYXN5bmMgKF9yZXF1ZXN0LCBfcmVwbHkpOiBQcm9taXNlPHR5cGVvZiB0aGlzLnN5bmNlci5hcGlzPiA9PiB7XG4gICAgICAgIHJldHVybiB0aGlzLnN5bmNlci5hcGlzO1xuICAgICAgfSxcbiAgICApO1xuXG4gICAgLy8gSGVhbHRoY2hlY2sgQVBJXG4gICAgc2VydmVyLmdldChcbiAgICAgIGAke3RoaXMuY29uZmlnLmFwaS5yb3V0ZS5wcmVmaXh9L2hlYWx0aGNoZWNrYCxcbiAgICAgIGFzeW5jIChfcmVxdWVzdCwgX3JlcGx5KTogUHJvbWlzZTxzdHJpbmc+ID0+IHtcbiAgICAgICAgcmV0dXJuIFwib2tcIjtcbiAgICAgIH0sXG4gICAgKTtcblxuICAgIC8vIFNvbmFtdSBVSSBBUEkgKOuhnOy7rCDtmZjqsr3sl5DshJzrp4wpXG4gICAgY29uc3QgeyBpc0xvY2FsIH0gPSBhd2FpdCBpbXBvcnQoXCIuLi91dGlscy9jb250cm9sbGVyXCIpO1xuICAgIGlmIChpc0xvY2FsKCkpIHtcbiAgICAgIGNvbnN0IHsgc29uYW11VUlBcGlQbHVnaW4gfSA9IGF3YWl0IGltcG9ydChcIi4uL3VpL2FwaVwiKTtcbiAgICAgIHNlcnZlci5yZWdpc3Rlcihzb25hbXVVSUFwaVBsdWdpbik7XG4gICAgfVxuXG4gICAgLy8gRGV2UnVubmVyIO2FjOyKpO2KuCDsl5Trk5ztj6zsnbjtirggKOuhnOy7rCDtmZjqsr0gKyBkZXZSdW5uZXIg7Zmc7ISx7ZmUIOyLnClcbiAgICBpZiAoaXNMb2NhbCgpICYmIHRoaXMuY29uZmlnLnRlc3Q/LmRldlJ1bm5lcj8uZW5hYmxlZCkge1xuICAgICAgY29uc3QgeyByZWdpc3RlckRldlRlc3RSb3V0ZXMgfSA9IGF3YWl0IGltcG9ydChcIi4uL3Rlc3RpbmcvZGV2LXRlc3Qtcm91dGVzXCIpO1xuICAgICAgYXdhaXQgcmVnaXN0ZXJEZXZUZXN0Um91dGVzKHNlcnZlciwgdGhpcy5jb25maWcudGVzdC5kZXZSdW5uZXIpO1xuICAgIH1cblxuICAgIGNvbnN0IHdlYlBhdGggPSBwYXRoLmpvaW4odGhpcy5hcHBSb290UGF0aCwgXCJ3ZWJcIik7XG4gICAgY29uc3QgaGFzV2ViID0gYXdhaXQgZXhpc3RzKHdlYlBhdGgpO1xuXG4gICAgLy8g7KCE7JetIGNvbXByZXNzIOyYteyFmCDqs4TsgrAgKHJvdXRlLmNvbXByZXNzOiB0cnVl7J28IOuVjCDsgqzsmqkpXG4gICAgY29uc3QgcGx1Z2luQ29tcHJlc3MgPSB0aGlzLmNvbmZpZy5zZXJ2ZXIucGx1Z2lucz8uY29tcHJlc3M7XG4gICAgY29uc3QgZ2xvYmFsQ29tcHJlc3NPcHRpb25zOiBDb21wcmVzc09wdGlvbnMgfCB1bmRlZmluZWQgPSBwbHVnaW5Db21wcmVzc1xuICAgICAgPyBwbHVnaW5Db21wcmVzcyA9PT0gdHJ1ZVxuICAgICAgICA/IHsgdGhyZXNob2xkOiAxMDI0LCBlbmNvZGluZ3M6IFtcImJyXCIsIFwiZ3ppcFwiLCBcImRlZmxhdGVcIl0gfVxuICAgICAgICA6IHtcbiAgICAgICAgICAgIHRocmVzaG9sZDogcGx1Z2luQ29tcHJlc3MudGhyZXNob2xkLFxuICAgICAgICAgICAgZW5jb2RpbmdzOiBwbHVnaW5Db21wcmVzcy5lbmNvZGluZ3MsXG4gICAgICAgICAgICBjdXN0b21UeXBlczogcGx1Z2luQ29tcHJlc3MuY3VzdG9tVHlwZXMsXG4gICAgICAgICAgfVxuICAgICAgOiB1bmRlZmluZWQ7XG5cbiAgICBpZiAoaXNMb2NhbCgpKSB7XG4gICAgICAvLyDroZzsu6wg6rCc67CcIO2ZmOqyvTogY2F0Y2gtYWxs66GcIEFQSeulvCDrj5nsoIEg66ek7Lmt7ZWY7JesIEhNUuydhCDsp4Dsm5Dtlanri4jri6QuXG4gICAgICAvLyBTT05BTVVfRElTQUJMRV9JTlRFR1JBVEVEX1dFQj15ZXProZwg7ISk7KCV7ZWY66m0IGRldl9hcGkg66qo65Oc7JeQ7IScIFZpdGUg7Ya17ZWp7J2EIOu5hO2ZnOyEse2ZlO2VoCDsiJgg7J6I7Iq164uI64ukLlxuICAgICAgY29uc3QgZGlzYWJsZUludGVncmF0ZWRXZWIgPSBwcm9jZXNzLmVudi5TT05BTVVfRElTQUJMRV9JTlRFR1JBVEVEX1dFQiA9PT0gXCJ5ZXNcIjtcbiAgICAgIGlmIChoYXNXZWIgJiYgIWRpc2FibGVJbnRlZ3JhdGVkV2ViKSB7XG4gICAgICAgIGF3YWl0IHRoaXMuc2V0dXBEZXZTZXJ2ZXJXaXRoVml0ZShzZXJ2ZXIsIHdlYlBhdGgsIGNvbmZpZyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLnNldHVwRGV2U2VydmVyKHNlcnZlciwgY29uZmlnKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgLy8g7ZSE66Gc642V7IWYIO2ZmOqyvTog6rCc67OEIEFQSSDrnbzsmrDtirggKyDsoJXsoIEg7YyM7J28IOyEnOu5mVxuICAgICAgZm9yIChjb25zdCBhcGkgb2YgdGhpcy5zeW5jZXIuYXBpcykge1xuICAgICAgICBpZiAodGhpcy5zeW5jZXIubW9kZWxzW2FwaS5tb2RlbE5hbWVdID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYOygleydmOuQmOyngCDslYrsnYAg66qo64247JeQIOygkeq3vCAke2FwaS5tb2RlbE5hbWV9YCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBAd2Vic29ja2V0IHJvdXRl64qUIHdzSGFuZGxlcuuhnCDrk7HroZ3tlZjqs6AsIOqwmeydgCBwYXRo7J2YIOydvOuwmCBIVFRQIEdFVOydgCA0MjYg7J2R64u17Jy866GcIHVwZ3JhZGXrpbwg6rCV7KCc7ZWoXG4gICAgICAgIGlmIChhcGkud2Vic29ja2V0T3B0aW9ucykge1xuICAgICAgICAgIHNlcnZlci5yb3V0ZSh7XG4gICAgICAgICAgICBtZXRob2Q6IFwiR0VUXCIsXG4gICAgICAgICAgICB1cmw6IHRoaXMuY29uZmlnLmFwaS5yb3V0ZS5wcmVmaXggKyBhcGkucGF0aCxcbiAgICAgICAgICAgIGhhbmRsZXI6IHRoaXMuY3JlYXRlV2ViU29ja2V0VXBncmFkZVJlcXVpcmVkSGFuZGxlcigpLFxuICAgICAgICAgICAgd3NIYW5kbGVyOiB0aGlzLmNyZWF0ZVdlYlNvY2tldEhhbmRsZXIoYXBpLCBjb25maWcpLFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgc2VydmVyLnJvdXRlKHtcbiAgICAgICAgICBtZXRob2Q6IGFwaS5vcHRpb25zLmh0dHBNZXRob2QgPz8gXCJHRVRcIixcbiAgICAgICAgICB1cmw6IHRoaXMuY29uZmlnLmFwaS5yb3V0ZS5wcmVmaXggKyBhcGkucGF0aCxcbiAgICAgICAgICBoYW5kbGVyOiB0aGlzLmNyZWF0ZUFwaUhhbmRsZXIoYXBpLCBjb25maWcpLFxuICAgICAgICAgIGNvbXByZXNzOiB0b0Zhc3RpZnlDb21wcmVzc09wdGlvbihhcGkub3B0aW9ucy5jb21wcmVzcywgZ2xvYmFsQ29tcHJlc3NPcHRpb25zKSxcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIC8vIO2UhOuhnOuNleyFmOyXkOyEnOuKlCB3ZWIg7IaM7IqkKGFwcFJvb3Qvd2ViKSDsnKDrrLTsmYAg66y06rSA7ZWY6rKMLFxuICAgICAgLy8gYXBpL3dlYi1kaXN0IOyhtOyerCDsl6zrtoDrpbwgc2V0dXBTdGF0aWNXZWJTZXJ2ZXIg64K067aA7JeQ7IScIO2MkOuLqO2VqeuLiOuLpC5cbiAgICAgIGF3YWl0IHRoaXMuc2V0dXBTdGF0aWNXZWJTZXJ2ZXIoc2VydmVyLCBjb25maWcsIGdsb2JhbENvbXByZXNzT3B0aW9ucyk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIGRldiDrqqjrk5wg6rO17Ya1OiBjYXRjaC1hbGzsl5DshJwgc3luY2VyLmFwaXPrpbwg64+Z7KCB7Jy866GcIO2DkOyDie2VmOyXrCBBUEkg7JqU7LKt7J2EIOyymOumrO2VqeuLiOuLpC5cbiAgICogc2VydmVyLnJvdXRlKCnroZwg6rCc67OEIOuTseuhne2VmOuptCBoYW5kbGVy6rCAIOqzoOygleuQmOyWtCBITVLsnbQg64+Z7J6R7ZWY7KeAIOyViuycvOuvgOuhnCxcbiAgICog66ekIOyalOyyreuniOuLpCBzeW5jZXIuYXBpc+ulvCDsobDtmoztlZjripQg7J20IOuwqeyLneydhCDsgqzsmqntlanri4jri6QuXG4gICAqXG4gICAqIOyalOyyreydtCAvYXBpKOygle2Zle2eiOuKlCB0aGlzLmNvbmZpZy5hcGkucm91dGUucHJlZml4KeuhnCDsi5zsnpHtlZjsp4Ag7JWK64qUIOqyveyasOudvOuptCBudWxs7J2EIOuwmO2ZmO2VmOupsCDrgZ3rg4Xri4jri6QuXG4gICAqL1xuICBwcml2YXRlIGhhbmRsZURldkFwaVJlcXVlc3QoXG4gICAgcmVxdWVzdDogRmFzdGlmeVJlcXVlc3QsXG4gICAgY29uZmlnOiBTb25hbXVGYXN0aWZ5Q29uZmlnLFxuICApOiAoKHJlcXVlc3Q6IEZhc3RpZnlSZXF1ZXN0LCByZXBseTogRmFzdGlmeVJlcGx5KSA9PiBQcm9taXNlPHVua25vd24+KSB8IG51bGwge1xuICAgIGNvbnN0IG1hdGNoZWRBcGkgPSB0aGlzLmZpbmRNYXRjaGVkQXBpKHJlcXVlc3QpO1xuXG4gICAgaWYgKCFtYXRjaGVkQXBpKSB7XG4gICAgICB0aHJvdyBuZXcgTm90Rm91bmRFeGNlcHRpb24oU0QoXCJlcnJvci5hcGkubm90Rm91bmRcIikpO1xuICAgIH1cblxuICAgIC8vIHdlYnNvY2tldCByb3V0ZeulvCDsnbzrsJggSFRUUOuhnCDsp4HsoJEg7Zi47Lac7ZWcIOqyveyasCA0MjbsnYQg64+M66Ck7KSYIHVwZ3JhZGUg7JeG7J20IOygkeq3vO2VmOuKlCDqsoPsnYQg7LCo64uo7ZWoXG4gICAgaWYgKG1hdGNoZWRBcGkud2Vic29ja2V0T3B0aW9ucykge1xuICAgICAgcmV0dXJuIHRoaXMuY3JlYXRlV2ViU29ja2V0VXBncmFkZVJlcXVpcmVkSGFuZGxlcigpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLmNyZWF0ZUFwaUhhbmRsZXIobWF0Y2hlZEFwaSwgY29uZmlnKTtcbiAgfVxuXG4gIHByaXZhdGUgZmluZE1hdGNoZWRBcGkocmVxdWVzdDogRmFzdGlmeVJlcXVlc3QpOiBFeHRlbmRlZEFwaSB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3QgdXJsID0gdGhpcy5nZXRQYXRobmFtZUZyb21VcmwocmVxdWVzdC51cmwpO1xuICAgIGNvbnN0IG1ldGhvZCA9IHJlcXVlc3QubWV0aG9kO1xuXG4gICAgaWYgKCF1cmwuc3RhcnRzV2l0aCh0aGlzLmNvbmZpZy5hcGkucm91dGUucHJlZml4KSkge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5zeW5jZXIuYXBpcy5maW5kKChhcGkpID0+IHtcbiAgICAgIGlmICh0aGlzLnN5bmNlci5tb2RlbHNbYXBpLm1vZGVsTmFtZV0gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICBjb25zdCBhcGlNZXRob2QgPSBhcGkub3B0aW9ucy5odHRwTWV0aG9kID8/IFwiR0VUXCI7XG4gICAgICBpZiAoYXBpTWV0aG9kICE9PSBtZXRob2QpIHJldHVybiBmYWxzZTtcblxuICAgICAgY29uc3QgZnVsbFBhdGggPSB0aGlzLmNvbmZpZy5hcGkucm91dGUucHJlZml4ICsgYXBpLnBhdGg7XG4gICAgICByZXR1cm4gdGhpcy5pc1BhdGhQYXR0ZXJuTWF0Y2goZnVsbFBhdGgsIHVybCk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogZGV2IGFwaSDrqqjrk5w6IFZpdGUg7JeG7J20IEFQSSDrj5nsoIEg65287Jqw7YyF66eMIOygnOqzte2VqeuLiOuLpC5cbiAgICogSE1S7J2EIOychO2VtCBjYXRjaC1hbGzsl5DshJwg66ekIOyalOyyreuniOuLpCBzeW5jZXIuYXBpc+ulvCDsobDtmoztlanri4jri6QuXG4gICAqL1xuICBwcml2YXRlIHNldHVwRGV2U2VydmVyKFxuICAgIHNlcnZlcjogRmFzdGlmeUluc3RhbmNlPFNlcnZlciwgSW5jb21pbmdNZXNzYWdlLCBTZXJ2ZXJSZXNwb25zZT4sXG4gICAgY29uZmlnOiBTb25hbXVGYXN0aWZ5Q29uZmlnLFxuICApOiB2b2lkIHtcbiAgICAvLyB1cGdyYWRl64qUIOyLpOyniOyggeycvOuhnCBHRVTsl5DshJzrp4wg7ISx66a97ZWY66+A66GcIEdFVCArIHdzSGFuZGxlciDsmYAg6re4IOyZuCBtZXRob2Trpbwg67OE64+EIHJvdXRl66GcIOu2hOumrO2VqFxuICAgIHNlcnZlci5yb3V0ZSh7XG4gICAgICBtZXRob2Q6IFwiR0VUXCIsXG4gICAgICB1cmw6IGAke3RoaXMuY29uZmlnLmFwaS5yb3V0ZS5wcmVmaXh9LypgLFxuICAgICAgaGFuZGxlcjogYXN5bmMgKHJlcXVlc3QsIHJlcGx5KSA9PiB7XG4gICAgICAgIGNvbnN0IGhhbmRsZXIgPSB0aGlzLmhhbmRsZURldkFwaVJlcXVlc3QocmVxdWVzdCwgY29uZmlnKTtcbiAgICAgICAgaWYgKGhhbmRsZXIpIHtcbiAgICAgICAgICByZXR1cm4gaGFuZGxlcihyZXF1ZXN0LCByZXBseSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8g65Ox66Gd65CcIEFQSeyZgCDsnbzsuZjtlZjsp4Ag7JWK64qUIOyalOyyreyXkCDrjIDtlZwgZmFsbGJhY2vsnoXri4jri6QuXG4gICAgICAgIHRocm93IG5ldyBOb3RGb3VuZEV4Y2VwdGlvbihTRChcImVycm9yLmFwaS5ub3RGb3VuZFwiKSk7XG4gICAgICB9LFxuICAgICAgd3NIYW5kbGVyOiBhc3luYyAoY29ubmVjdGlvbiwgcmVxdWVzdCkgPT4ge1xuICAgICAgICBhd2FpdCB0aGlzLmhhbmRsZURldldlYlNvY2tldFJlcXVlc3QoY29ubmVjdGlvbi5zb2NrZXQsIHJlcXVlc3QsIGNvbmZpZyk7XG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgc2VydmVyLnJvdXRlKHtcbiAgICAgIG1ldGhvZDogW1wiSEVBRFwiLCBcIlBPU1RcIiwgXCJQVVRcIiwgXCJERUxFVEVcIiwgXCJQQVRDSFwiXSxcbiAgICAgIHVybDogYCR7dGhpcy5jb25maWcuYXBpLnJvdXRlLnByZWZpeH0vKmAsXG4gICAgICBoYW5kbGVyOiBhc3luYyAocmVxdWVzdCwgcmVwbHkpID0+IHtcbiAgICAgICAgY29uc3QgaGFuZGxlciA9IHRoaXMuaGFuZGxlRGV2QXBpUmVxdWVzdChyZXF1ZXN0LCBjb25maWcpO1xuICAgICAgICBpZiAoaGFuZGxlcikge1xuICAgICAgICAgIHJldHVybiBoYW5kbGVyKHJlcXVlc3QsIHJlcGx5KTtcbiAgICAgICAgfVxuICAgICAgICB0aHJvdyBuZXcgTm90Rm91bmRFeGNlcHRpb24oU0QoXCJlcnJvci5hcGkubm90Rm91bmRcIikpO1xuICAgICAgfSxcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgdml0ZVNlcnZlcjogYW55ID0gbnVsbDtcblxuICAvKipcbiAgICogZGV2IGFsbCDrqqjrk5w6IFZpdGUgRGV2IFNlcnZlcuulvCDthrXtlantlZjsl6wgQVBJICsgU1NSICsgQ1NS7J2EIOuqqOuRkCDsoJzqs7Xtlanri4jri6QuXG4gICAqIEFQSSDrj5nsoIEg66ek7Lmt7J2AIGhhbmRsZURldkFwaVJlcXVlc3Trpbwg6rO17Jyg7ZWp64uI64ukLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBzZXR1cERldlNlcnZlcldpdGhWaXRlKFxuICAgIHNlcnZlcjogRmFzdGlmeUluc3RhbmNlPFNlcnZlciwgSW5jb21pbmdNZXNzYWdlLCBTZXJ2ZXJSZXNwb25zZT4sXG4gICAgd2ViUGF0aDogc3RyaW5nLFxuICAgIGNvbmZpZzogU29uYW11RmFzdGlmeUNvbmZpZyxcbiAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgLy8gQGZhc3RpZnkvbWlkZGllIOuTseuhnSAoQ29ubmVjdC1zdHlsZSBtaWRkbGV3YXJlIOyngOybkClcbiAgICBhd2FpdCBzZXJ2ZXIucmVnaXN0ZXIoKGF3YWl0IGltcG9ydChcIkBmYXN0aWZ5L21pZGRpZVwiKSkuZGVmYXVsdCk7XG5cbiAgICBjb25zdCB2aXRlID0gYXdhaXQgaW1wb3J0KFwidml0ZVwiKTtcbiAgICAvLyBAZmFzdGlmeS93ZWJzb2NrZXQg7ZSM65+s6re47J247J20IO2ZnOyEse2ZlOuQmOuptCBITVIgd2Vic29ja2V06rO8IHNlcnZlciBzb2NrZXTsnbQg7Lap64+M7ZWY66+A66GcIGRlZGljYXRlZCDtj6ztirjroZwg67aE66as7ZWoXG4gICAgY29uc3QgcmVxdWlyZXNEZWRpY2F0ZWRIbXJTZXJ2ZXIgPSBCb29sZWFuKHRoaXMuY29uZmlnLnNlcnZlci5wbHVnaW5zPy53cyk7XG4gICAgY29uc3QgaG1yID0gcmVzb2x2ZUludGVncmF0ZWRWaXRlSG1yT3B0aW9ucyh7XG4gICAgICBodHRwU2VydmVyOiBzZXJ2ZXIuc2VydmVyLFxuICAgICAgcmVxdWlyZXNEZWRpY2F0ZWRXZWJTb2NrZXRTZXJ2ZXI6IHJlcXVpcmVzRGVkaWNhdGVkSG1yU2VydmVyLFxuICAgIH0pO1xuXG4gICAgdGhpcy52aXRlU2VydmVyID0gYXdhaXQgdml0ZS5jcmVhdGVTZXJ2ZXIoe1xuICAgICAgcm9vdDogd2ViUGF0aCxcbiAgICAgIHNlcnZlcjoge1xuICAgICAgICBtaWRkbGV3YXJlTW9kZTogdHJ1ZSxcbiAgICAgICAgaG1yLFxuICAgICAgfSxcbiAgICAgIGFwcFR5cGU6IFwiY3VzdG9tXCIsXG4gICAgfSk7XG5cbiAgICAvLyBWaXRlIG1pZGRsZXdhcmUg65Ox66GdIChWaXRlIOyXkOyFiyDsspjrpqwpXG4gICAgc2VydmVyLnVzZSgocmVxLCByZXMsIG5leHQpID0+IHtcbiAgICAgIC8vIEFQSeyZgCBTb25hbXUgVUnripQgRmFzdGlmeSDrnbzsmrDtirjqsIAg7LKY66as7ZWY64+E66GdIHNraXBcbiAgICAgIGlmIChyZXEudXJsPy5zdGFydHNXaXRoKHRoaXMuY29uZmlnLmFwaS5yb3V0ZS5wcmVmaXgpIHx8IHJlcS51cmw/LnN0YXJ0c1dpdGgoXCIvc29uYW11LXVpXCIpKSB7XG4gICAgICAgIHJldHVybiBuZXh0KCk7XG4gICAgICB9XG4gICAgICAvLyDrgpjrqLjsp4DripQgVml0ZSBtaWRkbGV3YXJl66GcIOyghOuLrFxuICAgICAgcmV0dXJuIHRoaXMudml0ZVNlcnZlci5taWRkbGV3YXJlcyhyZXEsIHJlcywgbmV4dCk7XG4gICAgfSk7XG5cbiAgICAvLyBXUyB1cGdyYWRlIOqyveuhnChHRVQp7JmAIOydvOuwmCBIVFRQIOuplOyEnOuTnOulvCDrs4Trj4Qgcm91dGXroZwg67aE66as7ZW0IHdlYnNvY2tldCByb3V0ZeqwgCBIVE1MIGZhbGxiYWNr7JeQIOuoue2eiOyngCDslYrrj4TroZ0g7ZWoXG4gICAgc2VydmVyLnJvdXRlKHtcbiAgICAgIG1ldGhvZDogXCJHRVRcIixcbiAgICAgIHVybDogYCR7dGhpcy5jb25maWcuYXBpLnJvdXRlLnByZWZpeH0vKmAsXG4gICAgICBoYW5kbGVyOiBhc3luYyAocmVxdWVzdCwgcmVwbHkpID0+IHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gdGhpcy5oYW5kbGVEZXZBcGlSZXF1ZXN0KHJlcXVlc3QsIGNvbmZpZyk7XG4gICAgICAgIGlmIChyZXN1bHQpIHtcbiAgICAgICAgICByZXR1cm4gcmVzdWx0KHJlcXVlc3QsIHJlcGx5KTtcbiAgICAgICAgfVxuICAgICAgICB0aHJvdyBuZXcgTm90Rm91bmRFeGNlcHRpb24oU0QoXCJlcnJvci5hcGkubm90Rm91bmRcIikpO1xuICAgICAgfSxcbiAgICAgIHdzSGFuZGxlcjogYXN5bmMgKGNvbm5lY3Rpb24sIHJlcXVlc3QpID0+IHtcbiAgICAgICAgYXdhaXQgdGhpcy5oYW5kbGVEZXZXZWJTb2NrZXRSZXF1ZXN0KGNvbm5lY3Rpb24uc29ja2V0LCByZXF1ZXN0LCBjb25maWcpO1xuICAgICAgfSxcbiAgICB9KTtcblxuICAgIHNlcnZlci5yb3V0ZSh7XG4gICAgICBtZXRob2Q6IFtcIkhFQURcIiwgXCJQT1NUXCIsIFwiUFVUXCIsIFwiREVMRVRFXCIsIFwiUEFUQ0hcIl0sXG4gICAgICB1cmw6IGAke3RoaXMuY29uZmlnLmFwaS5yb3V0ZS5wcmVmaXh9LypgLFxuICAgICAgaGFuZGxlcjogYXN5bmMgKHJlcXVlc3QsIHJlcGx5KSA9PiB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IHRoaXMuaGFuZGxlRGV2QXBpUmVxdWVzdChyZXF1ZXN0LCBjb25maWcpO1xuICAgICAgICBpZiAocmVzdWx0KSB7XG4gICAgICAgICAgcmV0dXJuIHJlc3VsdChyZXF1ZXN0LCByZXBseSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgbmV3IE5vdEZvdW5kRXhjZXB0aW9uKFNEKFwiZXJyb3IuYXBpLm5vdEZvdW5kXCIpKTtcbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICAvLyBjYXRjaC1hbGwg65287Jqw7Yq47JeQ7IScIFNTUi9DU1Ig7LKY66asXG4gICAgLy8g6rCc67CcIO2ZmOqyveyXkOyEnOuKlCDrnbzsmrDtirjrs4QgY29tcHJlc3Mg7Ji17IWY7J2EIO2PrOq4sO2VmOqzoCBITVIg7J207KCQ7J2EIOy3qO2VqeuLiOuLpC5cbiAgICBzZXJ2ZXIucm91dGUoe1xuICAgICAgbWV0aG9kOiBbXCJHRVRcIiwgXCJIRUFEXCJdLFxuICAgICAgdXJsOiBcIi8qXCIsXG4gICAgICBoYW5kbGVyOiBhc3luYyAocmVxdWVzdCwgcmVwbHkpID0+IHtcbiAgICAgICAgY29uc3QgdXJsID0gcmVxdWVzdC51cmw7XG5cbiAgICAgICAgLy8gMS4gU1NSIOudvOyasO2KuCDsspjrpqxcbiAgICAgICAgY29uc3QgeyBtYXRjaFNTUlJvdXRlLCByZW5kZXJTU1IgfSA9IGF3YWl0IGltcG9ydChcIi4uL3NzclwiKTtcbiAgICAgICAgY29uc3Qgc3NyTWF0Y2ggPSBtYXRjaFNTUlJvdXRlKHVybCk7XG4gICAgICAgIGlmIChzc3JNYXRjaCkge1xuICAgICAgICAgIGNvbnNvbGUubG9nKGBbU1NSXSBNYXRjaGVkIHJvdXRlOiAke3Nzck1hdGNoLnJvdXRlLnBhdGh9YCk7XG4gICAgICAgICAgY29uc3QgaHRtbCA9IGF3YWl0IHJlbmRlclNTUihcbiAgICAgICAgICAgIHVybCxcbiAgICAgICAgICAgIHNzck1hdGNoLnJvdXRlLFxuICAgICAgICAgICAgc3NyTWF0Y2gucGFyYW1zLFxuICAgICAgICAgICAgcmVxdWVzdCxcbiAgICAgICAgICAgIHJlcGx5LFxuICAgICAgICAgICAgY29uZmlnLFxuICAgICAgICAgICAgdGhpcy52aXRlU2VydmVyLFxuICAgICAgICAgICk7XG4gICAgICAgICAgcmVwbHkudHlwZShcInRleHQvaHRtbFwiKTtcbiAgICAgICAgICByZXR1cm4gaHRtbDtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIDIuIENTUiBmYWxsYmFja1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGNvbnN0IGZzID0gYXdhaXQgaW1wb3J0KFwibm9kZTpmcy9wcm9taXNlc1wiKTtcbiAgICAgICAgICBsZXQgdGVtcGxhdGUgPSBhd2FpdCBmcy5yZWFkRmlsZShcbiAgICAgICAgICAgIHBhdGguam9pbih0aGlzLnZpdGVTZXJ2ZXIuY29uZmlnLnJvb3QsIFwiaW5kZXguaHRtbFwiKSxcbiAgICAgICAgICAgIFwidXRmLThcIixcbiAgICAgICAgICApO1xuICAgICAgICAgIHRlbXBsYXRlID0gYXdhaXQgdGhpcy52aXRlU2VydmVyLnRyYW5zZm9ybUluZGV4SHRtbCh1cmwsIHRlbXBsYXRlKTtcblxuICAgICAgICAgIHJlcGx5LnR5cGUoXCJ0ZXh0L2h0bWxcIik7XG4gICAgICAgICAgcmV0dXJuIHRlbXBsYXRlO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgdGhpcy52aXRlU2VydmVyLnNzckZpeFN0YWNrdHJhY2UoZSBhcyBFcnJvcik7XG4gICAgICAgICAgY29uc29sZS5lcnJvcihlKTtcbiAgICAgICAgICByZXBseS5zdGF0dXMoNTAwKTtcbiAgICAgICAgICByZXR1cm4gKGUgYXMgRXJyb3IpLm1lc3NhZ2U7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICAvLyDshJzrsoQg7KKF66OMIOyLnCBWaXRl64+EIOyiheujjFxuICAgIHNlcnZlci5hZGRIb29rKFwib25DbG9zZVwiLCBhc3luYyAoKSA9PiB7XG4gICAgICBhd2FpdCB0aGlzLnZpdGVTZXJ2ZXIuY2xvc2UoKTtcbiAgICB9KTtcblxuICAgIGNvbnN0IGNoYWxrID0gKGF3YWl0IGltcG9ydChcImNoYWxrXCIpKS5kZWZhdWx0O1xuICAgIGlmIChcInBvcnRcIiBpbiBobXIpIHtcbiAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICBjaGFsay5kaW0oXG4gICAgICAgICAgYOKckyBWaXRlIEhNUiB1c2luZyBkZWRpY2F0ZWQgd2Vic29ja2V0IHBvcnQgJHtobXIucG9ydH0gdG8gYXZvaWQgRmFzdGlmeSB3ZWJzb2NrZXQgY29uZmxpY3RzYCxcbiAgICAgICAgKSxcbiAgICAgICk7XG4gICAgfVxuICAgIGNvbnNvbGUubG9nKGNoYWxrLmRpbShcIuKckyBWaXRlIGRldiBzZXJ2ZXIgaW50ZWdyYXRlZFwiKSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHNldHVwU3RhdGljV2ViU2VydmVyKFxuICAgIHNlcnZlcjogRmFzdGlmeUluc3RhbmNlPFNlcnZlciwgSW5jb21pbmdNZXNzYWdlLCBTZXJ2ZXJSZXNwb25zZT4sXG4gICAgY29uZmlnOiBTb25hbXVGYXN0aWZ5Q29uZmlnLFxuICAgIGdsb2JhbENvbXByZXNzT3B0aW9uczogQ29tcHJlc3NPcHRpb25zIHwgdW5kZWZpbmVkLFxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAvLyDqsr3roZwg66qF7ZmV7ZmUOiBhcGkvd2ViLWRpc3QvY2xpZW50ICjsoJXsoIEg7YyM7J28KSwgYXBpL3dlYi1kaXN0L3NlcnZlciAoU1NSIGVudHJ5KSwgYXBpL2Rpc3Qvc3NyIChTU1Igcm91dGVzIC0gQVBJIOyGjOycoClcbiAgICBjb25zdCB3ZWJEaXN0UGF0aCA9IHBhdGguam9pbih0aGlzLmFwaVJvb3RQYXRoLCBcIndlYi1kaXN0XCIsIFwiY2xpZW50XCIpO1xuICAgIGNvbnN0IHNzclBhdGggPSBwYXRoLmpvaW4odGhpcy5hcGlSb290UGF0aCwgXCJ3ZWItZGlzdFwiLCBcInNlcnZlclwiKTtcbiAgICBjb25zdCBzc3JFbnRyeVBhdGggPSBwYXRoLmpvaW4oc3NyUGF0aCwgXCJlbnRyeS1zZXJ2ZXIuZ2VuZXJhdGVkLmpzXCIpO1xuICAgIGNvbnN0IHNzclJvdXRlc1BhdGggPSBwYXRoLmpvaW4odGhpcy5hcGlSb290UGF0aCwgXCJkaXN0XCIsIFwic3NyXCIsIFwicm91dGVzLmpzXCIpO1xuXG4gICAgaWYgKCEoYXdhaXQgZXhpc3RzKHdlYkRpc3RQYXRoKSkpIHtcbiAgICAgIGNvbnNvbGUud2Fybihg4pqgIFdlYiBkaXN0IG5vdCBmb3VuZDogJHt3ZWJEaXN0UGF0aH1gKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBTU1IgZW50cnkg7KG07J6sIOyXrOu2gCDtmZXsnbhcbiAgICBjb25zdCBzc3JBdmFpbGFibGUgPSBhd2FpdCBleGlzdHMoc3NyRW50cnlQYXRoKTtcblxuICAgIGlmICghc3NyQXZhaWxhYmxlKSB7XG4gICAgICBjb25zb2xlLndhcm4oYOKaoCBTU1IgZW50cnkgbm90IGZvdW5kOiAke3NzckVudHJ5UGF0aH1gKTtcbiAgICAgIGNvbnNvbGUud2FybihcIiAgU1NSIHdpbGwgYmUgZGlzYWJsZWQuIE9ubHkgQ1NSIHdpbGwgd29yay5cIik7XG4gICAgfVxuXG4gICAgLy8gU1NSIOudvOyasO2KuCDroZzrk5wgKHByb2R1Y3Rpb27sl5DshJzrp4wsIOyCrOyaqeyekCDtlITroZzsoJ3tirjsnZggc3NyL3JvdXRlcy50cylcbiAgICBpZiAoc3NyQXZhaWxhYmxlKSB7XG4gICAgICBpZiAoYXdhaXQgZXhpc3RzKHNzclJvdXRlc1BhdGgpKSB7XG4gICAgICAgIC8vIHRzLWxvYWRlcuudvOuptCBcImZpbGU6Ly9cIuuhnCDsi5zsnpHtlZjripQgZnVsbHktcmVzb2x2ZWQgcGF0aOunjCDrsJvquLDsl5Ag7J2066W8IOyymOumrO2VtOyjvOuKlCBpbXBvcnRNZW1iZXJz66W8IOyCrOyaqe2VtOyVvCDtlojqsqDsp4Drp4wsXG4gICAgICAgIC8vIOyXrOq4sOuKlCDtlITroZzrjZXshZgg7ZmY6rK97JeQ7IScIGxvYWRlciDsl4bsnbQg64+M7JWE6rCA6riwIOuVjOusuOyXkCBcIuynhOynnCBqcyDtjIzsnbxcIuydmCBcIuq3uOuDpVwiIOygiOuMgOqyveuhnOulvCDrsJTroZwgaW1wb3J07ZW064+EIOuQqeuLiOuLpC5cbiAgICAgICAgLy8g7J20IOuCtOyaqeydgCDsnbQg7ZWo7IiYIOuCtOyXkOyEnCDslYTrnpjsl5Ag64KY7JisIOuLpOuluCBpbXBvcnQg7Zi47Lac7JeQ64+EIOuPmeydvO2VmOqyjCDsoIHsmqnrkKnri4jri6QuXG4gICAgICAgIGF3YWl0IGltcG9ydChzc3JSb3V0ZXNQYXRoKTtcbiAgICAgICAgY29uc29sZS5sb2coXCLinJMgU1NSIHJvdXRlcyBsb2FkZWRcIik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zb2xlLndhcm4oYOKaoCBTU1Igcm91dGVzIG5vdCBmb3VuZDogJHtzc3JSb3V0ZXNQYXRofWApO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIOuhpOungSDsl4XrjbDsnbTtirgg64yA7J2ROiBhc3NldCBoYXNoIOu2iOydvOy5mCDsi5wg7ZiE7J6sIOuyhOyghCDsp4HsoJEg7ISc67mZXG4gICAgc2VydmVyLmdldChcIi9hc3NldHMvOmZpbGVuYW1lXCIsIGFzeW5jIChyZXF1ZXN0LCByZXBseSkgPT4ge1xuICAgICAgY29uc3QgcmVxdWVzdGVkRmlsZSA9IChyZXF1ZXN0LnBhcmFtcyBhcyB7IGZpbGVuYW1lOiBzdHJpbmcgfSkuZmlsZW5hbWU7XG4gICAgICBjb25zdCBhc3NldHNEaXIgPSBwYXRoLmpvaW4od2ViRGlzdFBhdGgsIFwiYXNzZXRzXCIpO1xuICAgICAgY29uc3Qgc2FmZUZpbGVQYXRoID0gdGhpcy5yZXNvbHZlUGF0aFdpdGhpbkJhc2VEaXIoYXNzZXRzRGlyLCByZXF1ZXN0ZWRGaWxlKTtcbiAgICAgIGlmIChzYWZlRmlsZVBhdGggPT09IG51bGwpIHtcbiAgICAgICAgcmVwbHkuc3RhdHVzKDQwMykuc2VuZCgpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBjb25zdCBub3JtYWxpemVkUmVxdWVzdGVkRmlsZSA9IHBhdGgucmVsYXRpdmUoYXNzZXRzRGlyLCBzYWZlRmlsZVBhdGgpLnJlcGxhY2UoL1xcXFwvZywgXCIvXCIpO1xuXG4gICAgICBjb25zdCBhc3NldFBhdGggPSBgL2Fzc2V0cy8ke25vcm1hbGl6ZWRSZXF1ZXN0ZWRGaWxlfWA7XG5cbiAgICAgIC8vIENhY2hlLUNvbnRyb2wg7Zek642UIOqysOyglVxuICAgICAgY29uc3QgZ2V0Q2FjaGVDb250cm9sRm9yQXNzZXQgPSAoKTogQ2FjaGVDb250cm9sQ29uZmlnID0+IHtcbiAgICAgICAgY29uc3QgY2FjaGVSZXE6IENhY2hlQ29udHJvbFJlcXVlc3QgPSB7XG4gICAgICAgICAgdHlwZTogXCJhc3NldHNcIixcbiAgICAgICAgICB1cmw6IHJlcXVlc3QudXJsLFxuICAgICAgICAgIHBhdGg6IGFzc2V0UGF0aCxcbiAgICAgICAgICBtZXRob2Q6IHJlcXVlc3QubWV0aG9kLFxuICAgICAgICB9O1xuXG4gICAgICAgIC8vIOyCrOyaqeyekCDsoJXsnZgg7ZW465Ok65+sIOyasOyEoFxuICAgICAgICBpZiAoY29uZmlnLmNhY2hlQ29udHJvbEhhbmRsZXIpIHtcbiAgICAgICAgICBjb25zdCByZXN1bHQgPSBjb25maWcuY2FjaGVDb250cm9sSGFuZGxlcihjYWNoZVJlcSk7XG4gICAgICAgICAgaWYgKHJlc3VsdCkgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIOq4sOuzuOqwkjogaW1tdXRhYmxlXG4gICAgICAgIHJldHVybiBDYWNoZVByZXNldHMuaW1tdXRhYmxlO1xuICAgICAgfTtcblxuICAgICAgLy8gaW5kZXgtKi5qcyDrmJDripQgaW5kZXgtKi5jc3Mg7JqU7LKt7J24IOqyveyasFxuICAgICAgaWYgKC9eaW5kZXgtW2EtZjAtOV0rXFwuKGpzfGNzcykkLy50ZXN0KG5vcm1hbGl6ZWRSZXF1ZXN0ZWRGaWxlKSkge1xuICAgICAgICBjb25zdCBleHQgPSBub3JtYWxpemVkUmVxdWVzdGVkRmlsZS5zcGxpdChcIi5cIikucG9wKCk7XG4gICAgICAgIGNvbnN0IGZpbGVzID0gYXdhaXQgZnMucmVhZGRpcihhc3NldHNEaXIpO1xuICAgICAgICBjb25zdCBjdXJyZW50RmlsZSA9IGZpbGVzLmZpbmQoKGYpID0+IGYuc3RhcnRzV2l0aChcImluZGV4LVwiKSAmJiBmLmVuZHNXaXRoKGAuJHtleHR9YCkpO1xuXG4gICAgICAgIGlmIChjdXJyZW50RmlsZSkge1xuICAgICAgICAgIGNvbnN0IGZpbGVQYXRoID0gcGF0aC5qb2luKGFzc2V0c0RpciwgY3VycmVudEZpbGUpO1xuICAgICAgICAgIGNvbnN0IGNvbnRlbnQgPSBhd2FpdCBmcy5yZWFkRmlsZShmaWxlUGF0aCk7XG4gICAgICAgICAgcmVwbHkudHlwZShleHQgPT09IFwianNcIiA/IFwiYXBwbGljYXRpb24vamF2YXNjcmlwdFwiIDogXCJ0ZXh0L2Nzc1wiKTtcbiAgICAgICAgICBhcHBseUNhY2hlSGVhZGVycyhyZXBseSwgZ2V0Q2FjaGVDb250cm9sRm9yQXNzZXQoKSk7XG4gICAgICAgICAgcmV0dXJuIHJlcGx5LnNlbmQoY29udGVudCk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8g7J2867CYIO2MjOydvCDshJzruZlcbiAgICAgIGNvbnN0IGZpbGVQYXRoID0gc2FmZUZpbGVQYXRoO1xuICAgICAgaWYgKGF3YWl0IGV4aXN0cyhmaWxlUGF0aCkpIHtcbiAgICAgICAgY29uc3QgY29udGVudCA9IGF3YWl0IGZzLnJlYWRGaWxlKGZpbGVQYXRoKTtcbiAgICAgICAgY29uc3QgZXh0ID0gbm9ybWFsaXplZFJlcXVlc3RlZEZpbGUuc3BsaXQoXCIuXCIpLnBvcCgpO1xuICAgICAgICByZXBseS50eXBlKGV4dCA9PT0gXCJqc1wiID8gXCJhcHBsaWNhdGlvbi9qYXZhc2NyaXB0XCIgOiBleHQgPT09IFwiY3NzXCIgPyBcInRleHQvY3NzXCIgOiBcIlwiKTtcbiAgICAgICAgaWYgKG5vcm1hbGl6ZWRSZXF1ZXN0ZWRGaWxlLmluY2x1ZGVzKFwiLVwiKSkge1xuICAgICAgICAgIGFwcGx5Q2FjaGVIZWFkZXJzKHJlcGx5LCBnZXRDYWNoZUNvbnRyb2xGb3JBc3NldCgpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVwbHkuc2VuZChjb250ZW50KTtcbiAgICAgIH1cblxuICAgICAgcmVwbHkuc3RhdHVzKDQwNCkuc2VuZCgpO1xuICAgIH0pO1xuXG4gICAgLy8gU1NSIOudvOyasO2KuCDqsJzrs4Qg65Ox66GdIChjb21wcmVzcyDsmLXshZjsnbQg65287Jqw7Yq467OE66GcIOyggeyaqeuQmOuPhOuhnSlcbiAgICBpZiAoc3NyQXZhaWxhYmxlKSB7XG4gICAgICBjb25zdCB7IGdldFNTUlJvdXRlcyB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vc3NyXCIpO1xuICAgICAgY29uc3QgeyByZW5kZXJTU1IgfSA9IGF3YWl0IGltcG9ydChcIi4uL3Nzci9yZW5kZXJlclwiKTtcbiAgICAgIGNvbnN0IHNzclJvdXRlcyA9IGdldFNTUlJvdXRlcygpO1xuXG4gICAgICBmb3IgKGNvbnN0IHJvdXRlIG9mIHNzclJvdXRlcykge1xuICAgICAgICBzZXJ2ZXIucm91dGUoe1xuICAgICAgICAgIG1ldGhvZDogW1wiR0VUXCIsIFwiSEVBRFwiXSxcbiAgICAgICAgICB1cmw6IHJvdXRlLnBhdGgsXG4gICAgICAgICAgY29tcHJlc3M6IHRvRmFzdGlmeUNvbXByZXNzT3B0aW9uKHJvdXRlLmNvbXByZXNzID8/IHRydWUsIGdsb2JhbENvbXByZXNzT3B0aW9ucyksXG4gICAgICAgICAgaGFuZGxlcjogYXN5bmMgKHJlcXVlc3QsIHJlcGx5KSA9PiB7XG4gICAgICAgICAgICBjb25zdCB1cmwgPSByZXF1ZXN0LnVybDtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKGBbU1NSXSBNYXRjaGVkIHJvdXRlOiAke3JvdXRlLnBhdGh9YCk7XG5cbiAgICAgICAgICAgIGNvbnN0IHBhcmFtcyA9IHRoaXMuZXh0cmFjdFBhdGhQYXJhbXMocm91dGUucGF0aCwgdXJsKTtcbiAgICAgICAgICAgIGNvbnN0IGh0bWwgPSBhd2FpdCByZW5kZXJTU1IodXJsLCByb3V0ZSwgcGFyYW1zLCByZXF1ZXN0LCByZXBseSwgY29uZmlnKTtcblxuICAgICAgICAgICAgcmVwbHkudHlwZShcInRleHQvaHRtbFwiKTtcbiAgICAgICAgICAgIHJldHVybiBodG1sO1xuICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIENTUiBvciBTdGF0aWMgRmlsZSBGYWxsYmFjayAoU1NSIOudvOyasO2KuOyXkCDrp6Tsua3rkJjsp4Ag7JWK64qUIOuqqOuToCDsmpTssq0pXG4gICAgc2VydmVyLnJvdXRlKHtcbiAgICAgIG1ldGhvZDogW1wiR0VUXCIsIFwiSEVBRFwiXSxcbiAgICAgIHVybDogXCIqXCIsXG4gICAgICBoYW5kbGVyOiBhc3luYyAocmVxdWVzdCwgcmVwbHkpID0+IHtcbiAgICAgICAgLy8gL2FwaSwgL3NvbmFtdS11aeuKlCA0MDQg6re464yA66GcXG4gICAgICAgIGlmIChyZXF1ZXN0LnVybC5zdGFydHNXaXRoKFwiL2FwaVwiKSB8fCByZXF1ZXN0LnVybC5zdGFydHNXaXRoKFwiL3NvbmFtdS11aVwiKSkge1xuICAgICAgICAgIHJlcGx5LnN0YXR1cyg0MDQpLnNlbmQoKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICAvLyBDU1LsmqkgQ2FjaGUtQ29udHJvbCDtl6TrjZQg7ISk7KCVXG4gICAgICAgIGlmIChjb25maWcuY2FjaGVDb250cm9sSGFuZGxlcikge1xuICAgICAgICAgIGNvbnN0IGNzckNhY2hlUmVxOiBDYWNoZUNvbnRyb2xSZXF1ZXN0ID0ge1xuICAgICAgICAgICAgdHlwZTogXCJjc3JcIixcbiAgICAgICAgICAgIHVybDogcmVxdWVzdC51cmwsXG4gICAgICAgICAgICBwYXRoOiByZXF1ZXN0LnVybC5zcGxpdChcIj9cIilbMF0sXG4gICAgICAgICAgICBtZXRob2Q6IHJlcXVlc3QubWV0aG9kLFxuICAgICAgICAgIH07XG4gICAgICAgICAgY29uc3QgY3NyQ2FjaGVDb25maWcgPSBjb25maWcuY2FjaGVDb250cm9sSGFuZGxlcihjc3JDYWNoZVJlcSk7XG5cbiAgICAgICAgICBpZiAoY3NyQ2FjaGVDb25maWcpIHtcbiAgICAgICAgICAgIGFwcGx5Q2FjaGVIZWFkZXJzKHJlcGx5LCBjc3JDYWNoZUNvbmZpZyk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8g7KCV7KCBIO2MjOydvOydtCDsobTsnqztlaAg6rK97JqwLCDsoJXsoIEg7YyM7J287J2EIOuovOyggCDshJzruZntlbTslbztlahcbiAgICAgICAgY29uc3QgcmVxdWVzdFBhdGggPSB0aGlzLmdldFBhdGhuYW1lRnJvbVVybChyZXF1ZXN0LnVybCk7XG4gICAgICAgIGNvbnN0IHNhZmVGaWxlUGF0aCA9IHRoaXMucmVzb2x2ZVBhdGhXaXRoaW5CYXNlRGlyKHdlYkRpc3RQYXRoLCByZXF1ZXN0UGF0aCk7XG4gICAgICAgIGlmIChzYWZlRmlsZVBhdGggPT09IG51bGwpIHtcbiAgICAgICAgICByZXBseS5zdGF0dXMoNDAzKS5zZW5kKCk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmIChhd2FpdCBmaWxlRXhpc3RzKHNhZmVGaWxlUGF0aCkpIHtcbiAgICAgICAgICBjb25zdCBjb250ZW50ID0gYXdhaXQgZnMucmVhZEZpbGUoc2FmZUZpbGVQYXRoKTtcbiAgICAgICAgICByZXR1cm4gcmVwbHkudHlwZShtaW1lTG9va3VwKHNhZmVGaWxlUGF0aCkgfHwgXCJhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW1cIikuc2VuZChjb250ZW50KTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIENTUiBmYWxsYmFjazogaW5kZXguaHRtbCDshJzruZlcbiAgICAgICAgY29uc3QgaW5kZXhQYXRoID0gcGF0aC5qb2luKHdlYkRpc3RQYXRoLCBcImluZGV4Lmh0bWxcIik7XG4gICAgICAgIHJldHVybiByZXBseS50eXBlKFwidGV4dC9odG1sXCIpLnNlbmQoYXdhaXQgZnMucmVhZEZpbGUoaW5kZXhQYXRoLCBcInV0Zi04XCIpKTtcbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICBjb25zb2xlLmxvZyhg4pyTIFN0YXRpYyB3ZWIgc2VydmVyIGNvbmZpZ3VyZWQgd2l0aCAke3NzckF2YWlsYWJsZSA/IFwiU1NSXCIgOiBcIkNTUiBvbmx5XCJ9IHN1cHBvcnRgKTtcbiAgfVxuXG4gIGNyZWF0ZUFwaUhhbmRsZXIoXG4gICAgYXBpOiBFeHRlbmRlZEFwaSxcbiAgICBjb25maWc6IFNvbmFtdUZhc3RpZnlDb25maWcsXG4gICk6IChyZXF1ZXN0OiBGYXN0aWZ5UmVxdWVzdCwgcmVwbHk6IEZhc3RpZnlSZXBseSkgPT4gUHJvbWlzZTx1bmtub3duPiB7XG4gICAgcmV0dXJuIGFzeW5jIChyZXF1ZXN0OiBGYXN0aWZ5UmVxdWVzdCwgcmVwbHk6IEZhc3RpZnlSZXBseSk6IFByb21pc2U8dW5rbm93bj4gPT4ge1xuICAgICAgLy8gQ29udGV4dCDsg53shLFcbiAgICAgIGNvbnN0IGNvbnRleHQ6IENvbnRleHQgPSBhd2FpdCB0aGlzLmNyZWF0ZUNvbnRleHQoY29uZmlnLCByZXF1ZXN0LCByZXBseSk7XG5cbiAgICAgIHJldHVybiB0aGlzLmFzeW5jTG9jYWxTdG9yYWdlLnJ1bih7IGNvbnRleHQgfSwgYXN5bmMgKCkgPT4ge1xuICAgICAgICAvLyBndWFyZHMg7LKY66asXG4gICAgICAgIHJ1bkd1YXJkcyh7XG4gICAgICAgICAgZ3VhcmRzOiBhcGkub3B0aW9ucy5ndWFyZHMsXG4gICAgICAgICAgY29uZmlnLFxuICAgICAgICAgIHJlcXVlc3QsXG4gICAgICAgICAgYXBpLFxuICAgICAgICB9KTtcblxuICAgICAgICAvLyDtjIzrnbzrr7jthLAg7KCV67O066GcIHpvZCDsiqTtgqTrp4gg67mM65OcXG4gICAgICAgIGNvbnN0IHsgZ2V0Wm9kT2JqZWN0RnJvbUFwaSB9ID0gYXdhaXQgaW1wb3J0KFwiLi9jb2RlLWNvbnZlcnRlcnNcIik7XG4gICAgICAgIGNvbnN0IFJlcVR5cGUgPSBnZXRab2RPYmplY3RGcm9tQXBpKGFwaSwgdGhpcy5zeW5jZXIudHlwZXMpO1xuXG4gICAgICAgIC8vIHJlcXVlc3Qg7YyM7IuxXG4gICAgICAgIGNvbnN0IHdoaWNoID0gYXBpLm9wdGlvbnMuaHR0cE1ldGhvZCA9PT0gXCJHRVRcIiA/IFwicXVlcnlcIiA6IFwiYm9keVwiO1xuICAgICAgICBsZXQgcmVxQm9keToge1xuICAgICAgICAgIFtrZXk6IHN0cmluZ106IHVua25vd247XG4gICAgICAgIH07XG4gICAgICAgIC8vIO2MjOydvCDsl4XroZzrk5wg7J6I64qUIOqyveyasCDsnoTsi5wg642w7J207YSwXG4gICAgICAgIGNvbnN0IGZpbGVzOiB7XG4gICAgICAgICAgYnVmZmVyZWRGaWxlczogQnVmZmVyZWRGaWxlW107XG4gICAgICAgICAgdXBsb2FkZWRGaWxlczogVXBsb2FkZWRGaWxlW107XG4gICAgICAgIH0gPSB7XG4gICAgICAgICAgYnVmZmVyZWRGaWxlczogW10sXG4gICAgICAgICAgdXBsb2FkZWRGaWxlczogW10sXG4gICAgICAgIH07XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjb25zdCBib2R5ID0gKHJlcXVlc3Rbd2hpY2hdID8/IHt9KSBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgICAgICAgICBpZiAoYXBpLnVwbG9hZE9wdGlvbnMpIHtcbiAgICAgICAgICAgIGNvbnN0IHBhcnRzID0gcmVxdWVzdC5wYXJ0cyh7XG4gICAgICAgICAgICAgIGxpbWl0czogYXBpLnVwbG9hZE9wdGlvbnMubGltaXRzLFxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIC8vIEZvcm1EYXRh7J2YIGZpZWxk65Ok7J2EIOyehOyLnOuhnCDsoIDsnqVcbiAgICAgICAgICAgIGNvbnN0IGZpZWxkczogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHt9O1xuXG4gICAgICAgICAgICBpZiAoYXBpLnVwbG9hZE9wdGlvbnMuY29uc3VtZSA9PT0gXCJidWZmZXJcIiB8fCAhYXBpLnVwbG9hZE9wdGlvbnMuY29uc3VtZSkge1xuICAgICAgICAgICAgICAvLyBCdWZmZXIg66qo65OcOiDrqZTrqqjrpqzsl5Ag66Gc65OcXG4gICAgICAgICAgICAgIGZvciBhd2FpdCAoY29uc3QgcGFydCBvZiBwYXJ0cykge1xuICAgICAgICAgICAgICAgIGlmIChwYXJ0LnR5cGUgPT09IFwiZmlsZVwiKSB7XG4gICAgICAgICAgICAgICAgICAvLyBDUklUSUNBTDog7YyM7J28IOyKpO2KuOumvOydhCDsponsi5wgY29uc3VtZe2VtOyVvCDri6TsnYwgcGFydOuhnCDrhJjslrTqsIgg7IiYIOyeiOydjFxuICAgICAgICAgICAgICAgICAgLy8g7J20IO2YuOy2nOydtCDsl4bsnLzrqbQg7KKF7KKFIG11bHRpcGFydCDtjIzsi7HsnbQgcGVuZGluZyDsg4Htg5zroZwg7YOA7J6E7JWE7JuDIOuwnOyDnVxuICAgICAgICAgICAgICAgICAgY29uc3QgYnVmZmVyID0gYXdhaXQgcGFydC50b0J1ZmZlcigpO1xuICAgICAgICAgICAgICAgICAgZmlsZXMuYnVmZmVyZWRGaWxlcy5wdXNoKG5ldyBCdWZmZXJlZEZpbGUocGFydCwgYnVmZmVyKSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChwYXJ0LnR5cGUgPT09IFwiZmllbGRcIikge1xuICAgICAgICAgICAgICAgICAgZmllbGRzW3BhcnQuZmllbGRuYW1lXSA9IFN0cmluZyhwYXJ0LnZhbHVlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSBpZiAoYXBpLnVwbG9hZE9wdGlvbnMuY29uc3VtZSA9PT0gXCJzdHJlYW1cIikge1xuICAgICAgICAgICAgICAvLyBTdHJlYW0g66qo65OcOiDsponsi5wg7KCA7J6l7IaM66GcIOyKpO2KuOumrOuwjVxuICAgICAgICAgICAgICBjb25zdCBkaXNrTmFtZSA9IGFwaS51cGxvYWRPcHRpb25zLmRlc3RpbmF0aW9uO1xuICAgICAgICAgICAgICBjb25zdCBkaXNrID0gdGhpcy5zdG9yYWdlLnVzZShkaXNrTmFtZSk7XG5cbiAgICAgICAgICAgICAgLy8g7Jqw7ISg7Iic7JyEOiDrjbDsvZTroIjsnbTthLAgPiDsoITsl60g7ISk7KCVID4g6riw67O46rCSXG4gICAgICAgICAgICAgIGNvbnN0IGtleUdlbmVyYXRvcjogS2V5R2VuZXJhdG9yID1cbiAgICAgICAgICAgICAgICBhcGkudXBsb2FkT3B0aW9ucy5rZXlHZW5lcmF0b3IgPz9cbiAgICAgICAgICAgICAgICB0aGlzLmNvbmZpZy5zZXJ2ZXIuc3RvcmFnZT8ua2V5R2VuZXJhdG9yID8/XG4gICAgICAgICAgICAgICAgZGVmYXVsdEtleUdlbmVyYXRvcjtcblxuICAgICAgICAgICAgICBmb3IgYXdhaXQgKGNvbnN0IHBhcnQgb2YgcGFydHMpIHtcbiAgICAgICAgICAgICAgICBpZiAocGFydC50eXBlID09PSBcImZpbGVcIikge1xuICAgICAgICAgICAgICAgICAgY29uc3Qga2V5ID0gYXdhaXQga2V5R2VuZXJhdG9yKHtcbiAgICAgICAgICAgICAgICAgICAgZmlsZW5hbWU6IHBhcnQuZmlsZW5hbWUsXG4gICAgICAgICAgICAgICAgICAgIG1pbWV0eXBlOiBwYXJ0Lm1pbWV0eXBlLFxuICAgICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICAgIGF3YWl0IGRpc2sucHV0U3RyZWFtKGtleSwgcGFydC5maWxlLCB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRlbnRUeXBlOiBwYXJ0Lm1pbWV0eXBlLFxuICAgICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICAgIGNvbnN0IHVybCA9IGF3YWl0IGRpc2suZ2V0VXJsKGtleSk7XG4gICAgICAgICAgICAgICAgICBjb25zdCBzaWduZWRVcmwgPSBhd2FpdCBkaXNrLmdldFNpZ25lZFVybChrZXkpO1xuXG4gICAgICAgICAgICAgICAgICBmaWxlcy51cGxvYWRlZEZpbGVzLnB1c2goXG4gICAgICAgICAgICAgICAgICAgIG5ldyBVcGxvYWRlZEZpbGUoe1xuICAgICAgICAgICAgICAgICAgICAgIGZpbGVuYW1lOiBwYXJ0LmZpbGVuYW1lLFxuICAgICAgICAgICAgICAgICAgICAgIG1pbWV0eXBlOiBwYXJ0Lm1pbWV0eXBlLFxuICAgICAgICAgICAgICAgICAgICAgIHNpemU6IHBhcnQuZmlsZS5ieXRlc1JlYWQsXG4gICAgICAgICAgICAgICAgICAgICAgdXJsLFxuICAgICAgICAgICAgICAgICAgICAgIHNpZ25lZFVybCxcbiAgICAgICAgICAgICAgICAgICAgICBrZXksXG4gICAgICAgICAgICAgICAgICAgICAgZGlza05hbWUsXG4gICAgICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHBhcnQudHlwZSA9PT0gXCJmaWVsZFwiKSB7XG4gICAgICAgICAgICAgICAgICBmaWVsZHNbcGFydC5maWVsZG5hbWVdID0gU3RyaW5nKHBhcnQudmFsdWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBxc+uhnCDspJHssqkg6rWs7KGwIO2MjOyLsTogcGFyYW1zW2NhdGVnb3J5XSDihpIgeyBwYXJhbXM6IHsgY2F0ZWdvcnk6IFwidGVzdFwiIH0gfVxuICAgICAgICAgICAgY29uc3QgcXMgPSBhd2FpdCBpbXBvcnQoXCJxc1wiKTtcbiAgICAgICAgICAgIGNvbnN0IHBhcnNlZCA9IHFzLmRlZmF1bHQucGFyc2UoZmllbGRzKTtcbiAgICAgICAgICAgIE9iamVjdC5hc3NpZ24oYm9keSwgcGFyc2VkKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb25zdCB7IGZhc3RpZnlDYXN0ZXIgfSA9IGF3YWl0IGltcG9ydChcIi4vY2FzdGVyXCIpO1xuICAgICAgICAgIHJlcUJvZHkgPSBmYXN0aWZ5Q2FzdGVyKFJlcVR5cGUpLnBhcnNlKGJvZHkpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgY29uc3QgeyBab2RFcnJvciB9ID0gYXdhaXQgaW1wb3J0KFwiem9kXCIpO1xuICAgICAgICAgIGlmIChlIGluc3RhbmNlb2YgWm9kRXJyb3IpIHtcbiAgICAgICAgICAgIGNvbnN0IHsgaHVtYW5pemVab2RFcnJvciB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vdXRpbHMvem9kLWVycm9yXCIpO1xuICAgICAgICAgICAgY29uc3QgbWVzc2FnZXMgPSBodW1hbml6ZVpvZEVycm9yKGUpXG4gICAgICAgICAgICAgIC5tYXAoKGlzc3VlKSA9PiBpc3N1ZS5tZXNzYWdlKVxuICAgICAgICAgICAgICAuam9pbihcIiBcIik7XG4gICAgICAgICAgICBjb25zdCB7IEJhZFJlcXVlc3RFeGNlcHRpb24gfSA9IGF3YWl0IGltcG9ydChcIi4uL2V4Y2VwdGlvbnMvc28tZXhjZXB0aW9uc1wiKTtcbiAgICAgICAgICAgIHRocm93IG5ldyBCYWRSZXF1ZXN0RXhjZXB0aW9uKG1lc3NhZ2VzIGFzIExvY2FsaXplZFN0cmluZywge1xuICAgICAgICAgICAgICB6b2RFcnJvcjogZSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aHJvdyBlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIENvbnRlbnQtVHlwZVxuICAgICAgICByZXBseS50eXBlKGFwaS5vcHRpb25zLmNvbnRlbnRUeXBlID8/IFwiYXBwbGljYXRpb24vanNvblwiKTtcblxuICAgICAgICAvLyBDYWNoZS1Db250cm9sIO2XpOuNlCDshKTsoJVcbiAgICAgICAgY29uc3QgYXBpQ2FjaGVDb25maWcgPSB0aGlzLmdldEFwaUNhY2hlQ29udHJvbChhcGksIHJlcXVlc3QsIGNvbmZpZyk7XG4gICAgICAgIGlmIChhcGlDYWNoZUNvbmZpZykge1xuICAgICAgICAgIGFwcGx5Q2FjaGVIZWFkZXJzKHJlcGx5LCBhcGlDYWNoZUNvbmZpZyk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyDsl4XroZzrk5wg7Ji17IWY7J20IOyeiOuKlCDqsr3smrAg7YyM7J28IOuNsOydtO2EsOulvCBDb250ZXh07JeQIOy2lOqwgFxuICAgICAgICBpZiAoYXBpLnVwbG9hZE9wdGlvbnMpIHtcbiAgICAgICAgICBjb25zdCBjb25zdW1lID0gYXBpLnVwbG9hZE9wdGlvbnMuY29uc3VtZSA/PyBcImJ1ZmZlclwiO1xuICAgICAgICAgIGlmIChjb25zdW1lID09PSBcImJ1ZmZlclwiKSB7XG4gICAgICAgICAgICBjb250ZXh0LmJ1ZmZlcmVkRmlsZXMgPSBmaWxlcy5idWZmZXJlZEZpbGVzO1xuICAgICAgICAgIH0gZWxzZSBpZiAoY29uc3VtZSA9PT0gXCJzdHJlYW1cIikge1xuICAgICAgICAgICAgY29udGV4dC51cGxvYWRlZEZpbGVzID0gZmlsZXMudXBsb2FkZWRGaWxlcztcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyDrqqjrjbgg66mU7IaM65OcIGFyZ3Mg7IOd7ISx7ZWY7JesIO2YuOy2nFxuICAgICAgICBjb25zdCB7IEFwaVBhcmFtVHlwZSB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vdHlwZXMvdHlwZXNcIik7XG4gICAgICAgIGNvbnN0IGFyZ3MgPSBhcGkucGFyYW1ldGVycy5tYXAoKHBhcmFtKSA9PiB7XG4gICAgICAgICAgLy8gQ29udGV4dCDsnbjsoJ3shZhcbiAgICAgICAgICBpZiAoQXBpUGFyYW1UeXBlLmlzQ29udGV4dChwYXJhbS50eXBlKSkge1xuICAgICAgICAgICAgcmV0dXJuIGNvbnRleHQ7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiByZXFCb2R5W3BhcmFtLm5hbWVdO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuaW52b2tlTW9kZWxNZXRob2QoYXBpLCBhcmdzLCByZXBseSk7XG4gICAgICB9KTtcbiAgICB9O1xuICB9XG5cbiAgLy8gV1MgcGF0aOulvCDsnbzrsJggSFRUUCBHRVTsnLzroZwg7Zi47Lac7ZWcIOqyveyasCA0MjYgKyBVcGdyYWRlIO2XpOuNlOuhnCDrqoXsi5zsoIHsnLzroZwgd2Vic29ja2V0IOygkeyGjeydhCDsnKDrj4TtlahcbiAgcHJpdmF0ZSBjcmVhdGVXZWJTb2NrZXRVcGdyYWRlUmVxdWlyZWRIYW5kbGVyKCkge1xuICAgIHJldHVybiBhc3luYyAoX3JlcXVlc3Q6IEZhc3RpZnlSZXF1ZXN0LCByZXBseTogRmFzdGlmeVJlcGx5KTogUHJvbWlzZTx2b2lkPiA9PiB7XG4gICAgICByZXBseS5oZWFkZXIoXCJjb25uZWN0aW9uXCIsIFwiVXBncmFkZVwiKS5oZWFkZXIoXCJ1cGdyYWRlXCIsIFwid2Vic29ja2V0XCIpLnN0YXR1cyg0MjYpLnNlbmQoe1xuICAgICAgICBtZXNzYWdlOiBcIldlYlNvY2tldCB1cGdyYWRlIHJlcXVpcmVkXCIsXG4gICAgICB9KTtcbiAgICB9O1xuICB9XG5cbiAgLy8gZGV2IOuqqOuTnOydmCBjYXRjaC1hbGwgd3NIYW5kbGVy7JeQ7IScIOyLpOygnCBXUyBBUEnroZwg65SU7Iqk7Yyo7LmY7ZWoLiDrp6Tsua3rkJjripQgcm91dGXqsIAg7JeG7Jy866m0IDEwMDjroZwg64ur7J2MXG4gIHByaXZhdGUgYXN5bmMgaGFuZGxlRGV2V2ViU29ja2V0UmVxdWVzdChcbiAgICBzb2NrZXQ6IFdlYlNvY2tldCxcbiAgICByZXF1ZXN0OiBGYXN0aWZ5UmVxdWVzdCxcbiAgICBjb25maWc6IFNvbmFtdUZhc3RpZnlDb25maWcsXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IG1hdGNoZWRBcGkgPSB0aGlzLmZpbmRNYXRjaGVkQXBpKHJlcXVlc3QpO1xuICAgIGlmICghbWF0Y2hlZEFwaT8ud2Vic29ja2V0T3B0aW9ucykge1xuICAgICAgY29uc3QgdHJhY2VDb250ZXh0ID0gdGhpcy53ZWJzb2NrZXRSdW50aW1lLnRlbGVtZXRyeUNvbnRyb2xsZXIuY3JlYXRlQ29ubmVjdGlvbkNvbnRleHQoe1xuICAgICAgICBoZWFkZXJzOiByZXF1ZXN0LmhlYWRlcnMsXG4gICAgICB9KTtcbiAgICAgIHRoaXMud2Vic29ja2V0UnVudGltZS50ZWxlbWV0cnlDb250cm9sbGVyLmVtaXQoe1xuICAgICAgICBuYW1lOiBcIndzLmNvbm5lY3Rpb24ucmVqZWN0ZWRcIixcbiAgICAgICAgbGV2ZWw6IFwid2FyblwiLFxuICAgICAgICBkZXRhaWw6IHtcbiAgICAgICAgICByZWFzb246IFwicm91dGVOb3RGb3VuZFwiLFxuICAgICAgICAgIHBhdGg6IHJlcXVlc3QudXJsLFxuICAgICAgICB9LFxuICAgICAgICB0cmFjZUlkOiB0cmFjZUNvbnRleHQudHJhY2VJZCxcbiAgICAgICAgc3BhbklkOiB0cmFjZUNvbnRleHQuc3BhbklkLFxuICAgICAgICBwYXJlbnRTcGFuSWQ6IHRyYWNlQ29udGV4dC5wYXJlbnRTcGFuSWQsXG4gICAgICAgIHNhbXBsZWQ6IHRyYWNlQ29udGV4dC5zYW1wbGVkLFxuICAgICAgfSk7XG4gICAgICBzb2NrZXQuY2xvc2UoMTAwOCwgXCJXZWJTb2NrZXQgcm91dGUgbm90IGZvdW5kXCIpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGhhbmRsZXIgPSB0aGlzLmNyZWF0ZVdlYlNvY2tldEhhbmRsZXIobWF0Y2hlZEFwaSwgY29uZmlnKTtcbiAgICBhd2FpdCBoYW5kbGVyKHsgc29ja2V0IH0sIHJlcXVlc3QpO1xuICB9XG5cbiAgLy8gV1Mgcm91dGUg7ZW465Ok65+s7J2YIOyLpO2WiSDsiJzshJzrpbwg6rOg7KCV7ZWoOlxuICAvLyAxKSBxdWVyeSBwYXJhbSDtjIzsi7HsnYQgYWN0aXZhdGlvbiDsoITsl5Ag64Gd64K0IGhhbmRzaGFrZSDsi6TtjKjqsIAgcmVnaXN0cnnsl5Ag64W47Lac65CY7KeAIOyViuqyjCDtlahcbiAgLy8gMikgYGFjdGl2ZTogZmFsc2Vg66GcIOuovOyggCDrk7HroZ3tlZwg65KkIGNvbnRleHQg7JWI7JeQ7IScIGd1YXJk66W8IOyLpO2Wie2VtCDsnbjspp0g7KCV67O066W8IOywuOyhsO2VoCDsiJgg7J6I6rKMIO2VqFxuICAvLyAzKSBjb250ZXh0L2d1YXJkIOykgOu5hOqwgCDrgZ3rgpwg65KkIGBhY3RpdmF0ZSgpYO2VtCDruIzroZzrk5zsupDsiqTtirjqsIAg7LSI6riw7ZmUIOykkeqwhCDsg4Htg5zrpbwg67O07KeAIOuqu+2VmOqyjCDtlahcbiAgLy8g7JeQ65+sIOuwnOyDnSDsi5zsl5DripQgcmVzb2x2ZVdlYlNvY2tldENsb3NlRGVzY3JpcHRvciDsoJXssYXsl5Ag65Sw6528IGNsb3NlIGNvZGXrpbwg66ek7ZWR7ZWoXG4gIHByaXZhdGUgY3JlYXRlV2ViU29ja2V0SGFuZGxlcihhcGk6IEV4dGVuZGVkQXBpLCBjb25maWc6IFNvbmFtdUZhc3RpZnlDb25maWcpIHtcbiAgICByZXR1cm4gYXN5bmMgKFxuICAgICAgY29ubmVjdGlvbjoge1xuICAgICAgICBzb2NrZXQ6IFdlYlNvY2tldDtcbiAgICAgIH0sXG4gICAgICByZXF1ZXN0OiBGYXN0aWZ5UmVxdWVzdCxcbiAgICApOiBQcm9taXNlPHZvaWQ+ID0+IHtcbiAgICAgIGNvbnN0IHNvY2tldCA9IGNvbm5lY3Rpb24uc29ja2V0O1xuICAgICAgbGV0IHdzQ29udGV4dDogV2ViU29ja2V0Q29udGV4dCB8IG51bGwgPSBudWxsO1xuICAgICAgbGV0IHJhd1dzOiBSZXR1cm5UeXBlPFdlYlNvY2tldFJ1bnRpbWVbXCJyZWdpc3RlckNvbm5lY3Rpb25cIl0+IHwgbnVsbCA9IG51bGw7XG4gICAgICBsZXQgcHJlUmVnaXN0ZXJQaGFzZTogXCJndWFyZFwiIHwgXCJxdWVyeVwiIHwgXCJyZWdpc3RlclwiIHwgXCJoYW5kbGVyXCIgPSBcImd1YXJkXCI7XG4gICAgICBsZXQgdHJhY2VDb250ZXh0OiBXZWJTb2NrZXRUZWxlbWV0cnlDb25uZWN0aW9uQ29udGV4dCA9IHt9O1xuXG4gICAgICB0cnkge1xuICAgICAgICB0cmFjZUNvbnRleHQgPSB0aGlzLndlYnNvY2tldFJ1bnRpbWUudGVsZW1ldHJ5Q29udHJvbGxlci5jcmVhdGVDb25uZWN0aW9uQ29udGV4dCh7XG4gICAgICAgICAgaGVhZGVyczogcmVxdWVzdC5oZWFkZXJzLFxuICAgICAgICB9KTtcblxuICAgICAgICBwcmVSZWdpc3RlclBoYXNlID0gXCJxdWVyeVwiO1xuICAgICAgICBjb25zdCByZXFCb2R5ID0gYXdhaXQgdGhpcy5wYXJzZVdlYlNvY2tldFJlcXVlc3RQYXJhbXMoYXBpLCByZXF1ZXN0KTtcbiAgICAgICAgcHJlUmVnaXN0ZXJQaGFzZSA9IFwicmVnaXN0ZXJcIjtcbiAgICAgICAgcmF3V3MgPSB0aGlzLndlYnNvY2tldFJ1bnRpbWUucmVnaXN0ZXJDb25uZWN0aW9uKHNvY2tldCwge1xuICAgICAgICAgIG91dEV2ZW50czogYXBpLndlYnNvY2tldE9wdGlvbnMhLm91dEV2ZW50cyxcbiAgICAgICAgICBpbkV2ZW50czogYXBpLndlYnNvY2tldE9wdGlvbnMhLmluRXZlbnRzLFxuICAgICAgICAgIG5hbWVzcGFjZTogYXBpLndlYnNvY2tldE9wdGlvbnMhLm5hbWVzcGFjZSxcbiAgICAgICAgICBoZWFydGJlYXQ6IGFwaS53ZWJzb2NrZXRPcHRpb25zIS5oZWFydGJlYXQsXG4gICAgICAgICAgYWN0aXZlOiBmYWxzZSxcbiAgICAgICAgICB0cmFjZUlkOiB0cmFjZUNvbnRleHQudHJhY2VJZCxcbiAgICAgICAgICBzcGFuSWQ6IHRyYWNlQ29udGV4dC5zcGFuSWQsXG4gICAgICAgICAgcGFyZW50U3BhbklkOiB0cmFjZUNvbnRleHQucGFyZW50U3BhbklkLFxuICAgICAgICAgIHNhbXBsZWQ6IHRyYWNlQ29udGV4dC5zYW1wbGVkLFxuICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCBzY29wZWRXcyA9IHRoaXMuY3JlYXRlU2NvcGVkV2ViU29ja2V0Q29ubmVjdGlvbihyYXdXcywgKCkgPT4gd3NDb250ZXh0KTtcbiAgICAgICAgd3NDb250ZXh0ID0gYXdhaXQgdGhpcy5jcmVhdGVXZWJTb2NrZXRDb250ZXh0KGNvbmZpZywgcmVxdWVzdCwgc2NvcGVkV3MpO1xuXG4gICAgICAgIGF3YWl0IHRoaXMuYXN5bmNMb2NhbFN0b3JhZ2UucnVuKHsgY29udGV4dDogd3NDb250ZXh0IH0sIGFzeW5jICgpID0+IHtcbiAgICAgICAgICBydW5HdWFyZHMoe1xuICAgICAgICAgICAgZ3VhcmRzOiBhcGkub3B0aW9ucy5ndWFyZHMsXG4gICAgICAgICAgICBjb25maWcsXG4gICAgICAgICAgICByZXF1ZXN0LFxuICAgICAgICAgICAgYXBpLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcblxuICAgICAgICB0aGlzLndlYnNvY2tldFJ1bnRpbWUuYWN0aXZhdGVDb25uZWN0aW9uKHJhd1dzLmlkKTtcbiAgICAgICAgcHJlUmVnaXN0ZXJQaGFzZSA9IFwiaGFuZGxlclwiO1xuXG4gICAgICAgIGNvbnN0IHsgQXBpUGFyYW1UeXBlIH0gPSBhd2FpdCBpbXBvcnQoXCIuLi90eXBlcy90eXBlc1wiKTtcbiAgICAgICAgY29uc3QgYXJncyA9IGFwaS5wYXJhbWV0ZXJzLm1hcCgocGFyYW0pID0+IHtcbiAgICAgICAgICBpZiAoQXBpUGFyYW1UeXBlLmlzQ29udGV4dChwYXJhbS50eXBlKSkge1xuICAgICAgICAgICAgcmV0dXJuIHdzQ29udGV4dDtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gcmVxQm9keVtwYXJhbS5uYW1lXTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgYXdhaXQgdGhpcy5hc3luY0xvY2FsU3RvcmFnZS5ydW4oeyBjb250ZXh0OiB3c0NvbnRleHQgfSwgYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIGF3YWl0IHRoaXMuaW52b2tlTW9kZWxNZXRob2QoYXBpLCBhcmdzKTtcbiAgICAgICAgfSk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBjb25zdCBjbG9zZURlc2NyaXB0b3IgPSByZXNvbHZlV2ViU29ja2V0Q2xvc2VEZXNjcmlwdG9yKGVycm9yKTtcbiAgICAgICAgaWYgKCFyYXdXcykge1xuICAgICAgICAgIHRoaXMud2Vic29ja2V0UnVudGltZS50ZWxlbWV0cnlDb250cm9sbGVyLmVtaXQoe1xuICAgICAgICAgICAgbmFtZTogXCJ3cy5jb25uZWN0aW9uLnJlamVjdGVkXCIsXG4gICAgICAgICAgICBsZXZlbDogY2xvc2VEZXNjcmlwdG9yLmxvZ0xldmVsID09PSBcIndhcm5cIiA/IFwid2FyblwiIDogXCJlcnJvclwiLFxuICAgICAgICAgICAgZGV0YWlsOiB7XG4gICAgICAgICAgICAgIHJlYXNvbjogcHJlUmVnaXN0ZXJQaGFzZSxcbiAgICAgICAgICAgICAgY29kZTogY2xvc2VEZXNjcmlwdG9yLmNvZGUsXG4gICAgICAgICAgICAgIHBhdGg6IGFwaS5wYXRoLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHRyYWNlSWQ6IHRyYWNlQ29udGV4dC50cmFjZUlkLFxuICAgICAgICAgICAgc3BhbklkOiB0cmFjZUNvbnRleHQuc3BhbklkLFxuICAgICAgICAgICAgcGFyZW50U3BhbklkOiB0cmFjZUNvbnRleHQucGFyZW50U3BhbklkLFxuICAgICAgICAgICAgc2FtcGxlZDogdHJhY2VDb250ZXh0LnNhbXBsZWQsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocmF3V3MpIHtcbiAgICAgICAgICByYXdXcy5jbG9zZShjbG9zZURlc2NyaXB0b3IuY29kZSwgY2xvc2VEZXNjcmlwdG9yLnJlYXNvbik7XG4gICAgICAgIH0gZWxzZSBpZiAoc29ja2V0LnJlYWR5U3RhdGUgPCAyKSB7XG4gICAgICAgICAgc29ja2V0LmNsb3NlKGNsb3NlRGVzY3JpcHRvci5jb2RlLCBjbG9zZURlc2NyaXB0b3IucmVhc29uKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLnNlcnZlcj8ubG9nKSB7XG4gICAgICAgICAgY29uc3QgcGF5bG9hZCA9IHtcbiAgICAgICAgICAgIGVycjogZXJyb3IsXG4gICAgICAgICAgICBtb2RlbE5hbWU6IGFwaS5tb2RlbE5hbWUsXG4gICAgICAgICAgICBtZXRob2ROYW1lOiBhcGkubWV0aG9kTmFtZSxcbiAgICAgICAgICAgIHBhdGg6IGFwaS5wYXRoLFxuICAgICAgICAgIH07XG4gICAgICAgICAgaWYgKGNsb3NlRGVzY3JpcHRvci5sb2dMZXZlbCA9PT0gXCJ3YXJuXCIpIHtcbiAgICAgICAgICAgIHRoaXMuc2VydmVyLmxvZy53YXJuKHBheWxvYWQsIGNsb3NlRGVzY3JpcHRvci5yZWFzb24pO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnNlcnZlci5sb2cuZXJyb3IocGF5bG9hZCwgY2xvc2VEZXNjcmlwdG9yLnJlYXNvbik7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmIChjbG9zZURlc2NyaXB0b3IubG9nTGV2ZWwgPT09IFwid2FyblwiKSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oY2xvc2VEZXNjcmlwdG9yLnJlYXNvbiwgZXJyb3IpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKGNsb3NlRGVzY3JpcHRvci5yZWFzb24sIGVycm9yKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9O1xuICB9XG5cbiAgLy8gb25NZXNzYWdlL29uQ2xvc2Xsspjrn7wg64uk66W4IHRpY2vsl5DshJwg7Iuk7ZaJ65CY64qUIGNhbGxiYWNr7J2AIEFMUyBjb250ZXh06rCAIOuBiuq4sOuvgOuhnCB3cmFwcGVy7JeQ7IScIGBhc3luY0xvY2FsU3RvcmFnZS5ydW5g7Jy866GcIOuLpOyLnCDqsJDsi7gg67O17JuQ7ZWoXG4gIC8vIHB1Ymxpc2gvam9pbi9sZWF2ZS9zZXRVc2VySWQg6rCZ7J2AIOymieyLnCDsi6TtlokgQVBJ64qUIOuLqOyInCDsnITsnoTrp4wg7ZWY6rOgLCBkZWZlcnJlZCBjYWxsYmFja+yXkOunjCBjb250ZXh0IOuzteybkOydhCDsoIHsmqntlahcbiAgcHJpdmF0ZSBjcmVhdGVTY29wZWRXZWJTb2NrZXRDb25uZWN0aW9uPFxuICAgIFRPdXQgZXh0ZW5kcyBXZWJTb2NrZXRFdmVudE1hcCxcbiAgICBUSW4gZXh0ZW5kcyBXZWJTb2NrZXRFdmVudE1hcCxcbiAgPihcbiAgICB3czogV2ViU29ja2V0Q29ubmVjdGlvbjxUT3V0LCBUSW4+LFxuICAgIGdldENvbnRleHQ6ICgpID0+IFdlYlNvY2tldENvbnRleHQgfCBudWxsLFxuICApOiBXZWJTb2NrZXRDb25uZWN0aW9uPFRPdXQsIFRJbj4ge1xuICAgIGNvbnN0IHRlbGVtZXRyeUNvbnRyb2xsZXIgPSB0aGlzLl93ZWJzb2NrZXRSdW50aW1lPy50ZWxlbWV0cnlDb250cm9sbGVyO1xuICAgIGNvbnN0IHJ1bkluQ29udGV4dCA9IDxUPihjYWxsYmFjazogKCkgPT4gVCk6IFQgPT4ge1xuICAgICAgY29uc3QgY29udGV4dCA9IGdldENvbnRleHQoKTtcbiAgICAgIGlmICghY29udGV4dCkge1xuICAgICAgICByZXR1cm4gY2FsbGJhY2soKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRoaXMuYXN5bmNMb2NhbFN0b3JhZ2UucnVuKHsgY29udGV4dCB9LCBjYWxsYmFjayk7XG4gICAgfTtcblxuICAgIHJldHVybiB7XG4gICAgICBnZXQgaWQoKSB7XG4gICAgICAgIHJldHVybiB3cy5pZDtcbiAgICAgIH0sXG4gICAgICBnZXQgbmFtZXNwYWNlKCkge1xuICAgICAgICByZXR1cm4gd3MubmFtZXNwYWNlO1xuICAgICAgfSxcbiAgICAgIGdldCBjbG9zZWQoKSB7XG4gICAgICAgIHJldHVybiB3cy5jbG9zZWQ7XG4gICAgICB9LFxuICAgICAgZ2V0IHVzZXJJZCgpIHtcbiAgICAgICAgcmV0dXJuIHdzLnVzZXJJZDtcbiAgICAgIH0sXG4gICAgICB0cmFuc3BvcnQ6IFwid3NcIixcbiAgICAgIHB1Ymxpc2hVbnR5cGVkKGV2ZW50LCBkYXRhKSB7XG4gICAgICAgIHdzLnB1Ymxpc2hVbnR5cGVkKGV2ZW50LCBkYXRhKTtcbiAgICAgIH0sXG4gICAgICBjbG9zZShjb2RlLCByZWFzb24pIHtcbiAgICAgICAgd3MuY2xvc2UoY29kZSwgcmVhc29uKTtcbiAgICAgIH0sXG4gICAgICBvbkNsb3NlKGNhbGxiYWNrKSB7XG4gICAgICAgIHdzLm9uQ2xvc2UoKCkgPT4gcnVuSW5Db250ZXh0KGNhbGxiYWNrKSk7XG4gICAgICB9LFxuICAgICAgb25NZXNzYWdlKGV2ZW50LCBoYW5kbGVyKSB7XG4gICAgICAgIHdzLm9uTWVzc2FnZShldmVudCwgKGRhdGEsIG1lc3NhZ2VUcmFjZUNvbnRleHQpID0+XG4gICAgICAgICAgcnVuSW5Db250ZXh0KGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGV2ZW50TmFtZSA9IFN0cmluZyhldmVudCk7XG4gICAgICAgICAgICBjb25zdCB0cmFjZUNvbnRleHQgPSBtZXNzYWdlVHJhY2VDb250ZXh0ID8/IGdldFdlYlNvY2tldFRlbGVtZXRyeUNvbnRleHQod3MpO1xuICAgICAgICAgICAgY29uc3Qgc3RhcnRlZEF0ID0gcGVyZm9ybWFuY2Uubm93KCk7XG5cbiAgICAgICAgICAgIHRlbGVtZXRyeUNvbnRyb2xsZXI/LmVtaXQoe1xuICAgICAgICAgICAgICBuYW1lOiBcIndzLmhhbmRsZXIuc3RhcnRlZFwiLFxuICAgICAgICAgICAgICBsZXZlbDogXCJkZWJ1Z1wiLFxuICAgICAgICAgICAgICBjb25uZWN0aW9uSWQ6IHdzLmlkLFxuICAgICAgICAgICAgICBuYW1lc3BhY2U6IHdzLm5hbWVzcGFjZSxcbiAgICAgICAgICAgICAgdXNlcklkOiB3cy51c2VySWQsXG4gICAgICAgICAgICAgIGRldGFpbDogeyBldmVudDogZXZlbnROYW1lIH0sXG4gICAgICAgICAgICAgIC4uLnRyYWNlQ29udGV4dCxcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBoYW5kbGVyKGRhdGEsIG1lc3NhZ2VUcmFjZUNvbnRleHQpO1xuICAgICAgICAgICAgICBjb25zdCBkdXJhdGlvbk1zID0gcGVyZm9ybWFuY2Uubm93KCkgLSBzdGFydGVkQXQ7XG4gICAgICAgICAgICAgIHRlbGVtZXRyeUNvbnRyb2xsZXI/LmVtaXQoe1xuICAgICAgICAgICAgICAgIG5hbWU6IFwid3MuaGFuZGxlci5jb21wbGV0ZWRcIixcbiAgICAgICAgICAgICAgICBsZXZlbDogXCJkZWJ1Z1wiLFxuICAgICAgICAgICAgICAgIGNvbm5lY3Rpb25JZDogd3MuaWQsXG4gICAgICAgICAgICAgICAgbmFtZXNwYWNlOiB3cy5uYW1lc3BhY2UsXG4gICAgICAgICAgICAgICAgdXNlcklkOiB3cy51c2VySWQsXG4gICAgICAgICAgICAgICAgZGV0YWlsOiB7IGV2ZW50OiBldmVudE5hbWUgfSxcbiAgICAgICAgICAgICAgICAuLi50cmFjZUNvbnRleHQsXG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICB0ZWxlbWV0cnlDb250cm9sbGVyPy5yZWNvcmRTcGFuKHtcbiAgICAgICAgICAgICAgICBvcGVyYXRpb25OYW1lOiBcIndzLm1lc3NhZ2UucHJvY2Vzc1wiLFxuICAgICAgICAgICAgICAgIGtpbmQ6IFwiaW50ZXJuYWxcIixcbiAgICAgICAgICAgICAgICBkdXJhdGlvbk1zLFxuICAgICAgICAgICAgICAgIHN0YXR1czogXCJ1bnNldFwiLFxuICAgICAgICAgICAgICAgIGNvbm5lY3Rpb25JZDogd3MuaWQsXG4gICAgICAgICAgICAgICAgbmFtZXNwYWNlOiB3cy5uYW1lc3BhY2UsXG4gICAgICAgICAgICAgICAgdXNlcklkOiB3cy51c2VySWQsXG4gICAgICAgICAgICAgICAgYXR0cmlidXRlczogeyBldmVudDogZXZlbnROYW1lIH0sXG4gICAgICAgICAgICAgICAgLi4udHJhY2VDb250ZXh0LFxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgIGNvbnN0IGR1cmF0aW9uTXMgPSBwZXJmb3JtYW5jZS5ub3coKSAtIHN0YXJ0ZWRBdDtcbiAgICAgICAgICAgICAgdGVsZW1ldHJ5Q29udHJvbGxlcj8uZW1pdCh7XG4gICAgICAgICAgICAgICAgbmFtZTogXCJ3cy5oYW5kbGVyLmZhaWxlZFwiLFxuICAgICAgICAgICAgICAgIGxldmVsOiBcImVycm9yXCIsXG4gICAgICAgICAgICAgICAgY29ubmVjdGlvbklkOiB3cy5pZCxcbiAgICAgICAgICAgICAgICBuYW1lc3BhY2U6IHdzLm5hbWVzcGFjZSxcbiAgICAgICAgICAgICAgICB1c2VySWQ6IHdzLnVzZXJJZCxcbiAgICAgICAgICAgICAgICBkZXRhaWw6IHsgZXZlbnQ6IGV2ZW50TmFtZSB9LFxuICAgICAgICAgICAgICAgIC4uLnRyYWNlQ29udGV4dCxcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIHRlbGVtZXRyeUNvbnRyb2xsZXI/LnJlY29yZFNwYW4oe1xuICAgICAgICAgICAgICAgIG9wZXJhdGlvbk5hbWU6IFwid3MubWVzc2FnZS5wcm9jZXNzXCIsXG4gICAgICAgICAgICAgICAga2luZDogXCJpbnRlcm5hbFwiLFxuICAgICAgICAgICAgICAgIGR1cmF0aW9uTXMsXG4gICAgICAgICAgICAgICAgc3RhdHVzOiBcImVycm9yXCIsXG4gICAgICAgICAgICAgICAgY29ubmVjdGlvbklkOiB3cy5pZCxcbiAgICAgICAgICAgICAgICBuYW1lc3BhY2U6IHdzLm5hbWVzcGFjZSxcbiAgICAgICAgICAgICAgICB1c2VySWQ6IHdzLnVzZXJJZCxcbiAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzOiB7IGV2ZW50OiBldmVudE5hbWUgfSxcbiAgICAgICAgICAgICAgICBlcnJvclR5cGU6IGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5uYW1lIDogdHlwZW9mIGVycm9yLFxuICAgICAgICAgICAgICAgIC4uLnRyYWNlQ29udGV4dCxcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pLFxuICAgICAgICApO1xuICAgICAgfSxcbiAgICAgIHB1Ymxpc2goZXZlbnQsIGRhdGEpIHtcbiAgICAgICAgd3MucHVibGlzaChldmVudCwgZGF0YSk7XG4gICAgICB9LFxuICAgICAgd2FpdEZvckNsb3NlKCkge1xuICAgICAgICByZXR1cm4gd3Mud2FpdEZvckNsb3NlKCk7XG4gICAgICB9LFxuICAgICAgam9pbihyb29tSWQpIHtcbiAgICAgICAgd3Muam9pbihyb29tSWQpO1xuICAgICAgfSxcbiAgICAgIGxlYXZlKHJvb21JZCkge1xuICAgICAgICB3cy5sZWF2ZShyb29tSWQpO1xuICAgICAgfSxcbiAgICAgIHNldFVzZXJJZCh1c2VySWQpIHtcbiAgICAgICAgd3Muc2V0VXNlcklkKHVzZXJJZCk7XG4gICAgICB9LFxuICAgICAgY2xlYXJVc2VySWQoKSB7XG4gICAgICAgIHdzLmNsZWFyVXNlcklkKCk7XG4gICAgICB9LFxuICAgIH07XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHBhcnNlV2ViU29ja2V0UmVxdWVzdFBhcmFtcyhcbiAgICBhcGk6IEV4dGVuZGVkQXBpLFxuICAgIHJlcXVlc3Q6IEZhc3RpZnlSZXF1ZXN0LFxuICApOiBQcm9taXNlPFJlY29yZDxzdHJpbmcsIHVua25vd24+PiB7XG4gICAgY29uc3QgeyBnZXRab2RPYmplY3RGcm9tQXBpIH0gPSBhd2FpdCBpbXBvcnQoXCIuL2NvZGUtY29udmVydGVyc1wiKTtcbiAgICBjb25zdCBSZXFUeXBlID0gZ2V0Wm9kT2JqZWN0RnJvbUFwaShhcGksIHRoaXMuc3luY2VyLnR5cGVzKTtcblxuICAgIHRyeSB7XG4gICAgICBjb25zdCB7IGZhc3RpZnlDYXN0ZXIgfSA9IGF3YWl0IGltcG9ydChcIi4vY2FzdGVyXCIpO1xuICAgICAgcmV0dXJuIGZhc3RpZnlDYXN0ZXIoUmVxVHlwZSkucGFyc2UoKHJlcXVlc3QucXVlcnkgPz8ge30pIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+KTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBjb25zdCB7IFpvZEVycm9yIH0gPSBhd2FpdCBpbXBvcnQoXCJ6b2RcIik7XG4gICAgICBpZiAoZSBpbnN0YW5jZW9mIFpvZEVycm9yKSB7XG4gICAgICAgIGNvbnN0IHsgaHVtYW5pemVab2RFcnJvciB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vdXRpbHMvem9kLWVycm9yXCIpO1xuICAgICAgICBjb25zdCBtZXNzYWdlcyA9IGh1bWFuaXplWm9kRXJyb3IoZSlcbiAgICAgICAgICAubWFwKChpc3N1ZSkgPT4gaXNzdWUubWVzc2FnZSlcbiAgICAgICAgICAuam9pbihcIiBcIik7XG4gICAgICAgIGNvbnN0IHsgQmFkUmVxdWVzdEV4Y2VwdGlvbiB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vZXhjZXB0aW9ucy9zby1leGNlcHRpb25zXCIpO1xuICAgICAgICB0aHJvdyBuZXcgQmFkUmVxdWVzdEV4Y2VwdGlvbihtZXNzYWdlcyBhcyBMb2NhbGl6ZWRTdHJpbmcsIHtcbiAgICAgICAgICB6b2RFcnJvcjogZSxcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIHRocm93IGU7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFVSTOyXkOyEnCBwYXRoIHBhcmFtc+ulvCDstpTstpztlanri4jri6QuXG4gICAqIOyYiDogcGF0dGVybj1cIi9hZG1pbi9jb21wYW5pZXMvOmNvbXBhbnlJZFwiLCB1cmw9XCIvYWRtaW4vY29tcGFuaWVzLzEyM1wiIOKGkiB7IGNvbXBhbnlJZDogXCIxMjNcIiB9XG4gICAqL1xuICBwcml2YXRlIGV4dHJhY3RQYXRoUGFyYW1zKHBhdHRlcm46IHN0cmluZywgdXJsOiBzdHJpbmcpOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+IHtcbiAgICBjb25zdCBwYXR0ZXJuUGFydHMgPSBwYXR0ZXJuLnNwbGl0KFwiL1wiKS5maWx0ZXIoQm9vbGVhbik7XG4gICAgY29uc3QgdXJsUGFydHMgPSB0aGlzLmdldFBhdGhuYW1lRnJvbVVybCh1cmwpLnNwbGl0KFwiL1wiKS5maWx0ZXIoQm9vbGVhbik7XG4gICAgY29uc3QgcGFyYW1zOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge307XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHBhdHRlcm5QYXJ0cy5sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKHBhdHRlcm5QYXJ0c1tpXS5zdGFydHNXaXRoKFwiOlwiKSkge1xuICAgICAgICBwYXJhbXNbcGF0dGVyblBhcnRzW2ldLnNsaWNlKDEpXSA9IHVybFBhcnRzW2ldO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcGFyYW1zO1xuICB9XG5cbiAgcHJpdmF0ZSBpc1BhdGhQYXR0ZXJuTWF0Y2gocGF0dGVybjogc3RyaW5nLCB1cmw6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IHBhdHRlcm5QYXJ0cyA9IHBhdHRlcm4uc3BsaXQoXCIvXCIpLmZpbHRlcihCb29sZWFuKTtcbiAgICBjb25zdCB1cmxQYXJ0cyA9IHRoaXMuZ2V0UGF0aG5hbWVGcm9tVXJsKHVybCkuc3BsaXQoXCIvXCIpLmZpbHRlcihCb29sZWFuKTtcblxuICAgIGlmIChwYXR0ZXJuUGFydHMubGVuZ3RoICE9PSB1cmxQYXJ0cy5sZW5ndGgpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHBhdHRlcm5QYXJ0cy5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3QgcGF0dGVyblBhcnQgPSBwYXR0ZXJuUGFydHNbaV07XG4gICAgICBjb25zdCB1cmxQYXJ0ID0gdXJsUGFydHNbaV07XG4gICAgICBpZiAocGF0dGVyblBhcnQuc3RhcnRzV2l0aChcIjpcIikpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBpZiAocGF0dGVyblBhcnQgIT09IHVybFBhcnQpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRQYXRobmFtZUZyb21VcmwodXJsOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIHJldHVybiB1cmwuc3BsaXQoXCI/XCIpWzBdO1xuICB9XG5cbiAgcHJpdmF0ZSByZXNvbHZlUGF0aFdpdGhpbkJhc2VEaXIoYmFzZURpcjogc3RyaW5nLCBpbnB1dFBhdGg6IHN0cmluZyk6IHN0cmluZyB8IG51bGwge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBkZWNvZGVkID0gZGVjb2RlVVJJQ29tcG9uZW50KGlucHV0UGF0aCkucmVwbGFjZSgvXFxcXC9nLCBcIi9cIik7XG4gICAgICBpZiAoZGVjb2RlZC5pbmNsdWRlcyhcIlxcMFwiKSkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHJlbGF0aXZlUGF0aCA9IGRlY29kZWQucmVwbGFjZSgvXlxcLysvLCBcIlwiKTtcbiAgICAgIGNvbnN0IHJlc29sdmVkUGF0aCA9IHBhdGgucmVzb2x2ZShiYXNlRGlyLCByZWxhdGl2ZVBhdGgpO1xuICAgICAgY29uc3QgcmVsYXRpdmVGcm9tQmFzZSA9IHBhdGgucmVsYXRpdmUoYmFzZURpciwgcmVzb2x2ZWRQYXRoKTtcbiAgICAgIGlmIChyZWxhdGl2ZUZyb21CYXNlLnN0YXJ0c1dpdGgoXCIuLlwiKSB8fCBwYXRoLmlzQWJzb2x1dGUocmVsYXRpdmVGcm9tQmFzZSkpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzb2x2ZWRQYXRoO1xuICAgIH0gY2F0Y2gge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEFQSSDsnZHri7Xsl5Ag7KCB7Jqp7ZWgIENhY2hlLUNvbnRyb2wg7ISk7KCV7J2EIOqysOygle2VqeuLiOuLpC5cbiAgICog7Jqw7ISg7Iic7JyEOiDqsJzrs4Qg7KeA7KCVID4gY2FjaGVDb250cm9sSGFuZGxlclxuICAgKi9cbiAgcHJpdmF0ZSBnZXRBcGlDYWNoZUNvbnRyb2woXG4gICAgYXBpOiBFeHRlbmRlZEFwaSxcbiAgICByZXF1ZXN0OiBGYXN0aWZ5UmVxdWVzdCxcbiAgICBjb25maWc6IFNvbmFtdUZhc3RpZnlDb25maWcsXG4gICkge1xuICAgIC8vIOuNsOy9lOugiOydtO2EsCDshKTsoJUg7Jqw7ISgXG4gICAgaWYgKGFwaS5vcHRpb25zLmNhY2hlQ29udHJvbCkge1xuICAgICAgcmV0dXJuIGFwaS5vcHRpb25zLmNhY2hlQ29udHJvbDtcbiAgICB9XG5cbiAgICAvLyDsoITsl60g7ZW465Ok65+sXG4gICAgaWYgKGNvbmZpZy5jYWNoZUNvbnRyb2xIYW5kbGVyKSB7XG4gICAgICBjb25zdCBjYWNoZVJlcTogQ2FjaGVDb250cm9sUmVxdWVzdCA9IHtcbiAgICAgICAgdHlwZTogXCJhcGlcIixcbiAgICAgICAgdXJsOiByZXF1ZXN0LnVybCxcbiAgICAgICAgcGF0aDogcmVxdWVzdC5yb3V0ZU9wdGlvbnM/LnVybCA/PyByZXF1ZXN0LnVybC5zcGxpdChcIj9cIilbMF0sXG4gICAgICAgIG1ldGhvZDogcmVxdWVzdC5tZXRob2QsXG4gICAgICAgIGFwaSxcbiAgICAgIH07XG4gICAgICBjb25zdCByZXN1bHQgPSBjb25maWcuY2FjaGVDb250cm9sSGFuZGxlcihjYWNoZVJlcSk7XG4gICAgICBpZiAocmVzdWx0KSByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgLyoqXG4gICAqIFNTUuyaqSBBUEkg7Zi47LacIChIVFRQIOyYpOuyhO2XpOuTnCDsl4bsnbQg7KeB7KCRIO2YuOy2nClcbiAgICogY3JlYXRlQXBpSGFuZGxlcuydmCDroZzsp4HsnYQg7J6s7IKs7Jqp7ZWY65CYLCByZXF1ZXN0IO2MjOyLsSDrjIDsi6AgcGFyYW1zIOyngeygkSDsgqzsmqlcbiAgICovXG4gIGFzeW5jIGludm9rZUFwaUZvclNTUihcbiAgICBhcGk6IEV4dGVuZGVkQXBpLFxuICAgIHBhcmFtczogYW55W10sXG4gICAgY29uZmlnOiBTb25hbXVGYXN0aWZ5Q29uZmlnLFxuICAgIHJlcXVlc3Q6IEZhc3RpZnlSZXF1ZXN0LFxuICAgIHJlcGx5OiBGYXN0aWZ5UmVwbHksXG4gICk6IFByb21pc2U8dW5rbm93bj4ge1xuICAgIC8vIENvbnRleHQg7IOd7ISxICjquLDsobQg66mU7IaM65OcIOyerOyCrOyaqSlcbiAgICBjb25zdCBjb250ZXh0ID0gYXdhaXQgdGhpcy5jcmVhdGVDb250ZXh0KGNvbmZpZywgcmVxdWVzdCwgcmVwbHkpO1xuXG4gICAgcmV0dXJuIHRoaXMuYXN5bmNMb2NhbFN0b3JhZ2UucnVuKHsgY29udGV4dCB9LCBhc3luYyAoKSA9PiB7XG4gICAgICAvLyBhcmdzIOyDneyEsTogQ29udGV4dCDtjIzrnbzrr7jthLDripQg7KO87J6FLCDrgpjrqLjsp4DripQgcGFyYW1z7JeQ7IScIOqwgOyguOyYpOq4sFxuICAgICAgY29uc3QgeyBBcGlQYXJhbVR5cGUgfSA9IGF3YWl0IGltcG9ydChcIi4uL3R5cGVzL3R5cGVzXCIpO1xuICAgICAgbGV0IHBhcmFtc0luZGV4ID0gMDtcbiAgICAgIGNvbnN0IGFyZ3MgPSBhcGkucGFyYW1ldGVycy5tYXAoKHBhcmFtKSA9PiB7XG4gICAgICAgIGlmIChBcGlQYXJhbVR5cGUuaXNDb250ZXh0KHBhcmFtLnR5cGUpKSB7XG4gICAgICAgICAgcmV0dXJuIGNvbnRleHQ7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHBhcmFtc1twYXJhbXNJbmRleCsrXTtcbiAgICAgIH0pO1xuXG4gICAgICAvLyDrqqjrjbgg66mU7ISc65OcIO2YuOy2nCAo6riw7KG0IOuplOyEnOuTnCDsnqzsgqzsmqkpXG4gICAgICByZXR1cm4gdGhpcy5pbnZva2VNb2RlbE1ldGhvZChhcGksIGFyZ3MsIHJlcGx5KTtcbiAgICB9KTtcbiAgfVxuXG4gIC8vIFdTIOqyveuhnOyXkOyEnOuKlCBIVFRQIHJlcGx56rCAIOyXhuycvOuvgOuhnCByZXBseeulvCBvcHRpb25hbOuhnCDrsJvslYQg6rO17Ya1IO2YuOy2nCDqsr3roZzrpbwg7Jyg7KeA7ZWoXG4gIGFzeW5jIGludm9rZU1vZGVsTWV0aG9kKFxuICAgIGFwaTogRXh0ZW5kZWRBcGksXG4gICAgYXJnczogdW5rbm93bltdLFxuICAgIHJlcGx5PzogRmFzdGlmeVJlcGx5LFxuICApOiBQcm9taXNlPHVua25vd24+IHtcbiAgICBjb25zdCBtb2RlbCA9IHRoaXMuc3luY2VyLm1vZGVsc1thcGkubW9kZWxOYW1lXTtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCAobW9kZWwgYXMgYW55KVthcGkubWV0aG9kTmFtZV0uYXBwbHkobW9kZWwsIGFyZ3MpO1xuICAgIHJlcGx5Py50eXBlKGFwaS5vcHRpb25zLmNvbnRlbnRUeXBlID8/IFwiYXBwbGljYXRpb24vanNvblwiKTtcblxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICBhc3luYyBjcmVhdGVDb250ZXh0KFxuICAgIGNvbmZpZzogU29uYW11RmFzdGlmeUNvbmZpZyxcbiAgICByZXF1ZXN0OiBGYXN0aWZ5UmVxdWVzdCxcbiAgICByZXBseTogRmFzdGlmeVJlcGx5LFxuICApOiBQcm9taXNlPENvbnRleHQ+IHtcbiAgICAvLyBjcmVhdGVTU0VGYWN0b3J5IO2VqOyImOyXkCDrr7jrpqwgcmVxdWVzdOydmCBzb2NrZXTqs7wgcmVwbHnrpbwg67CU7J2465SpLlxuICAgIGNvbnN0IHsgY3JlYXRlU1NFRmFjdG9yeSB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vc3RyZWFtL3NzZVwiKTtcbiAgICBjb25zdCBjcmVhdGVTU0UgPSAoPFQgZXh0ZW5kcyBab2RPYmplY3Q+KFxuICAgICAgX3JlcXVlc3Q6IEZhc3RpZnlSZXF1ZXN0LFxuICAgICAgX3JlcGx5OiBGYXN0aWZ5UmVwbHksXG4gICAgICBfZXZlbnRzOiBULFxuICAgICkgPT4gY3JlYXRlU1NFRmFjdG9yeShfcmVxdWVzdC5zb2NrZXQsIF9yZXBseSwgX2V2ZW50cykpLmJpbmQobnVsbCwgcmVxdWVzdCwgcmVwbHkpO1xuXG4gICAgLy8gbG9jYWxlIOqwkOyngFxuICAgIGNvbnN0IGxvY2FsZSA9XG4gICAgICB0aGlzLmRldGVjdExvY2FsZShyZXF1ZXN0LmhlYWRlcnNbXCJhY2NlcHQtbGFuZ3VhZ2VcIl0sIHRoaXMuY29uZmlnLmkxOG4uc3VwcG9ydGVkTG9jYWxlcykgPz9cbiAgICAgIHRoaXMuY29uZmlnLmkxOG4uZGVmYXVsdExvY2FsZTtcblxuICAgIC8vIGF1dGggY29udGV4dCDstpTqsIBcbiAgICBjb25zdCBoZWFkZXJzID0gY29udmVydEZhc3RpZnlIZWFkZXJzVG9TdGFuZGFyZChyZXF1ZXN0LmhlYWRlcnMpO1xuICAgIGNvbnN0IHNlc3Npb24gPSAoYXdhaXQgdGhpcy5fYXV0aD8uYXBpLmdldFNlc3Npb24oeyBoZWFkZXJzIH0pKSA/PyBudWxsO1xuXG4gICAgY29uc3QgY29udGV4dDogQ29udGV4dCA9IGF3YWl0IFByb21pc2UucmVzb2x2ZShcbiAgICAgIGNvbmZpZy5jb250ZXh0UHJvdmlkZXIoXG4gICAgICAgIHtcbiAgICAgICAgICB0cmFuc3BvcnQ6IFwiaHR0cFwiLFxuICAgICAgICAgIHJlcXVlc3QsXG4gICAgICAgICAgcmVwbHksXG4gICAgICAgICAgaGVhZGVyczogcmVxdWVzdC5oZWFkZXJzLFxuICAgICAgICAgIGNyZWF0ZVNTRSxcbiAgICAgICAgICBuYWl0ZVN0b3JlOiBuZXcgTWFwKCksXG4gICAgICAgICAgbG9jYWxlLFxuICAgICAgICAgIC8vIGF1dGhcbiAgICAgICAgICB1c2VyOiBzZXNzaW9uPy51c2VyID8/IG51bGwsXG4gICAgICAgICAgc2Vzc2lvbjogc2Vzc2lvbj8uc2Vzc2lvbiA/PyBudWxsLFxuICAgICAgICB9LFxuICAgICAgICByZXF1ZXN0LFxuICAgICAgICByZXBseSxcbiAgICAgICksXG4gICAgKTtcbiAgICByZXR1cm4gY29udGV4dDtcbiAgfVxuXG4gIC8vIHNlc3Npb24vbG9jYWxlL3N0b3JlIOqwmeydgCDqs7XthrUgc3RhdGXripQgSFRUUCBjb250ZXh07JmAIOqzteycoO2VmOuQmCwgcmVwbHkvY3JlYXRlU1NFIOqwmeydgCBIVFRQIOyghOyaqSBoZWxwZXLripQg64W47Lac7ZWY7KeAIOyViuydjFxuICAvLyDsgqzsmqnsnpDqsIAgd2Vic29ja2V0Q29udGV4dFByb3ZpZGVy66W8IOyjvOuptCDqt7jrjIDroZwg7JyE7J6E7ZWY6rOgLCDsl4bsnLzrqbQg6riw7KG0IGNvbnRleHRQcm92aWRlcuulvCByZXBseS9TU0Ugc3R1YuqzvCDtlajqu5gg7J6s7Zmc7Jqp7ZWoXG4gIGFzeW5jIGNyZWF0ZVdlYlNvY2tldENvbnRleHQoXG4gICAgY29uZmlnOiBTb25hbXVGYXN0aWZ5Q29uZmlnLFxuICAgIHJlcXVlc3Q6IEZhc3RpZnlSZXF1ZXN0LFxuICAgIHdzOiBXZWJTb2NrZXRDb250ZXh0W1wid3NcIl0sXG4gICk6IFByb21pc2U8V2ViU29ja2V0Q29udGV4dD4ge1xuICAgIGNvbnN0IGxvY2FsZSA9XG4gICAgICB0aGlzLmRldGVjdExvY2FsZShyZXF1ZXN0LmhlYWRlcnNbXCJhY2NlcHQtbGFuZ3VhZ2VcIl0sIHRoaXMuY29uZmlnLmkxOG4uc3VwcG9ydGVkTG9jYWxlcykgPz9cbiAgICAgIHRoaXMuY29uZmlnLmkxOG4uZGVmYXVsdExvY2FsZTtcblxuICAgIGNvbnN0IGhlYWRlcnMgPSBjb252ZXJ0RmFzdGlmeUhlYWRlcnNUb1N0YW5kYXJkKHJlcXVlc3QuaGVhZGVycyk7XG4gICAgY29uc3Qgc2Vzc2lvbiA9IChhd2FpdCB0aGlzLl9hdXRoPy5hcGkuZ2V0U2Vzc2lvbih7IGhlYWRlcnMgfSkpID8/IG51bGw7XG5cbiAgICBjb25zdCBkZWZhdWx0Q29udGV4dCA9IHtcbiAgICAgIHRyYW5zcG9ydDogXCJ3c1wiIGFzIGNvbnN0LFxuICAgICAgcmVxdWVzdCxcbiAgICAgIGhlYWRlcnM6IHJlcXVlc3QuaGVhZGVycyxcbiAgICAgIHdzLFxuICAgICAgbmFpdGVTdG9yZTogbmV3IE1hcCgpLFxuICAgICAgbG9jYWxlLFxuICAgICAgdXNlcjogc2Vzc2lvbj8udXNlciA/PyBudWxsLFxuICAgICAgc2Vzc2lvbjogc2Vzc2lvbj8uc2Vzc2lvbiA/PyBudWxsLFxuICAgIH07XG5cbiAgICBpZiAoY29uZmlnLndlYnNvY2tldENvbnRleHRQcm92aWRlcikge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgLi4uKGF3YWl0IFByb21pc2UucmVzb2x2ZShjb25maWcud2Vic29ja2V0Q29udGV4dFByb3ZpZGVyKGRlZmF1bHRDb250ZXh0LCByZXF1ZXN0KSkpLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICAvLyByZXBseS9jcmVhdGVTU0Xsl5Ag7J2Y7KG07ZWY64qUIGNvbnRleHRQcm92aWRlcuqwgCDsnojsnLzrqbQg7KaJ7IucIOyXkOufrOulvCDrjZjsoLggdHJhbnNwb3J0IG1pc3VzZeulvCDruajrpqwg65Oc65+s64OEXG4gICAgY29uc3QgcmVwbHlTdHViID0gY3JlYXRlV2ViU29ja2V0UmVwbHlTdHViKCk7XG4gICAgY29uc3QgY3JlYXRlU1NFID0gPFQgZXh0ZW5kcyBab2RPYmplY3Q+KF9ldmVudHM6IFQpID0+IHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgXCJjcmVhdGVTU0UgaXMgbm90IGF2YWlsYWJsZSBpbiB3ZWJzb2NrZXQgY29udGV4dC4gRGVmaW5lIHdlYnNvY2tldENvbnRleHRQcm92aWRlciBpZiB5b3VyIGNvbnRleHQgc2V0dXAgZGVwZW5kcyBvbiBTU0UgaGVscGVycy5cIixcbiAgICAgICk7XG4gICAgfTtcbiAgICBjb25zdCBodHRwTGlrZUNvbnRleHQgPSBhd2FpdCBQcm9taXNlLnJlc29sdmUoXG4gICAgICBjb25maWcuY29udGV4dFByb3ZpZGVyKFxuICAgICAgICB7XG4gICAgICAgICAgdHJhbnNwb3J0OiBcImh0dHBcIixcbiAgICAgICAgICByZXF1ZXN0LFxuICAgICAgICAgIHJlcGx5OiByZXBseVN0dWIsXG4gICAgICAgICAgaGVhZGVyczogcmVxdWVzdC5oZWFkZXJzLFxuICAgICAgICAgIGNyZWF0ZVNTRSxcbiAgICAgICAgICBuYWl0ZVN0b3JlOiBkZWZhdWx0Q29udGV4dC5uYWl0ZVN0b3JlLFxuICAgICAgICAgIGxvY2FsZSxcbiAgICAgICAgICB1c2VyOiBkZWZhdWx0Q29udGV4dC51c2VyLFxuICAgICAgICAgIHNlc3Npb246IGRlZmF1bHRDb250ZXh0LnNlc3Npb24sXG4gICAgICAgIH0sXG4gICAgICAgIHJlcXVlc3QsXG4gICAgICAgIHJlcGx5U3R1YixcbiAgICAgICksXG4gICAgKTtcblxuICAgIGNvbnN0IHtcbiAgICAgIHRyYW5zcG9ydDogX3RyYW5zcG9ydCxcbiAgICAgIHJlcGx5OiBfcmVwbHksXG4gICAgICBjcmVhdGVTU0U6IF9jcmVhdGVTU0UsXG4gICAgICBidWZmZXJlZEZpbGVzOiBfYnVmZmVyZWRGaWxlcyxcbiAgICAgIHVwbG9hZGVkRmlsZXM6IF91cGxvYWRlZEZpbGVzLFxuICAgICAgLi4ucmVzdFxuICAgIH0gPSBodHRwTGlrZUNvbnRleHQ7XG5cbiAgICByZXR1cm4ge1xuICAgICAgLi4ucmVzdCxcbiAgICAgIHRyYW5zcG9ydDogXCJ3c1wiLFxuICAgICAgcmVxdWVzdCxcbiAgICAgIGhlYWRlcnM6IHJlcXVlc3QuaGVhZGVycyxcbiAgICAgIHdzLFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogQWNjZXB0LUxhbmd1YWdlIO2XpOuNlOyXkOyEnCDsp4Dsm5DtlZjripQgbG9jYWxl7J2EIOywvuyKteuLiOuLpC5cbiAgICogQGV4YW1wbGUgXCJrby1LUixrbztxPTAuOSxlbjtxPTAuOFwiIOKGkiBcImtvXCJcbiAgICovXG4gIHByaXZhdGUgZGV0ZWN0TG9jYWxlKFxuICAgIGFjY2VwdExhbmd1YWdlOiBzdHJpbmcgfCB1bmRlZmluZWQsXG4gICAgc3VwcG9ydGVkOiBzdHJpbmdbXSxcbiAgKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgICBpZiAoIWFjY2VwdExhbmd1YWdlKSByZXR1cm4gdW5kZWZpbmVkO1xuXG4gICAgLy8gQWNjZXB0LUxhbmd1YWdlOiBrby1LUixrbztxPTAuOSxlbjtxPTAuOFxuICAgIGNvbnN0IGxhbmdzID0gYWNjZXB0TGFuZ3VhZ2Uuc3BsaXQoXCIsXCIpLm1hcCgobGFuZykgPT4ge1xuICAgICAgY29uc3QgW2NvZGVdID0gbGFuZy5zcGxpdChcIjtcIik7XG4gICAgICByZXR1cm4gY29kZS50cmltKCkuc3BsaXQoXCItXCIpWzBdOyAvLyBrby1LUiDihpIga29cbiAgICB9KTtcblxuICAgIHJldHVybiBsYW5ncy5maW5kKChsYW5nKSA9PiBzdXBwb3J0ZWQuaW5jbHVkZXMobGFuZykpO1xuICB9XG5cbiAgYXN5bmMgc3RhcnRXYXRjaGVyKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIC8vIHdhdGNoZXIg66qo65OI7J2AIGZpbGUtcGF0dGVybnMg4oaSIFNvbmFtdSDsiJztmZjsnYQg7ZS87ZWY6riwIOychO2VtCBkeW5hbWljIGltcG9ydCDtlanri4jri6QuXG4gICAgY29uc3QgeyBzZXR1cFdhdGNoZXIgfSA9IGF3YWl0IGltcG9ydChcIi4uL3N5bmNlci93YXRjaGVyXCIpO1xuICAgIHRoaXMud2F0Y2hlciA9IGF3YWl0IHNldHVwV2F0Y2hlcigoZmlsZUV2ZW50cykgPT4gdGhpcy5ydW5IbXJTeW5jQ3ljbGUoZmlsZUV2ZW50cykpO1xuICB9XG5cbiAgLyoqXG4gICAqIFdhdGNoZXLqsIAgMTAwbXMgYmF0Y2jroZwg66qo7J2AIGZpbGVFdmVudHMg7ZWY64KY7JeQIOuMgO2VtCDtlZwg67KI7J2YIEhNUi9zeW5jIOyCrOydtO2BtOydhCDrj5Xri4jri6QuXG4gICAqIGJhdGNoIO2BkOyeiSDrjZXsl5Ag7ZWcIOyLnOygkOyXkCDtlZjrgpjrp4wg7Iuk7ZaJ65Co7J20IOuztOyepeuQqeuLiOuLpCAoZXZlbnQtYmF0Y2hlcuqwgCDsp4HroKztmZQpLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBydW5IbXJTeW5jQ3ljbGUoZmlsZUV2ZW50czogTWFwPEFic29sdXRlUGF0aCwgXCJjaGFuZ2VcIiB8IFwiYWRkXCI+KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3Qgc3RhcnRlZEF0ID0gRGF0ZS5ub3coKTtcblxuICAgIGZvciAoY29uc3QgW2ZpbGVQYXRoLCBldmVudF0gb2YgZmlsZUV2ZW50cykge1xuICAgICAgY29uc3QgcmVsYXRpdmVQYXRoID0gcGF0aC5yZWxhdGl2ZSh0aGlzLmFwcFJvb3RQYXRoLCBmaWxlUGF0aCk7XG4gICAgICBjb25zb2xlLmxvZyhjaGFsay5ib2xkKGBEZXRlY3RlZCgke2V2ZW50fSk6ICR7Y2hhbGsuYmx1ZShyZWxhdGl2ZVBhdGgpfWApKTtcbiAgICB9XG5cbiAgICAvLyDrs7jssrQ6IOuzgOqyvSDtnaHsiJggKyDssrTtgazshKwg6rCx7IugLlxuICAgIGF3YWl0IHRoaXMuc3luY2VyLmhtckFuZFN5bmMoZmlsZUV2ZW50cyk7XG4gICAgYXdhaXQgdGhpcy5zeW5jZXIucmVuZXdDaGVja3N1bXMoKTtcblxuICAgIGNvbnN0IHRvdGFsVGltZSA9IERhdGUubm93KCkgLSBzdGFydGVkQXQ7XG4gICAgY29uc3QgbXNnID0gYEhNUiBEb25lISAke2NoYWxrLmJvbGQud2hpdGUoYCR7dG90YWxUaW1lfW1zYCl9YDtcbiAgICBjb25zb2xlLmxvZyhjaGFsay5ibGFjay5iZ0dyZWVuKGNlbnRlclRleHQobXNnKSkpO1xuICB9XG5cbiAgLypcbiAgICAgQSBmdW5jdGlvbiB0aGF0IGF1dG9tYXRpY2FsbHkgaGFuZGxlcyBpbml0IGFuZCBkZXN0cm95IHdoZW4gdXNpbmcgU29uYW11IHZpYSBzY3JpcHRzLlxuICAqL1xuICBhc3luYyBydW5TY3JpcHQoZm46ICgpID0+IFByb21pc2U8dm9pZD4pIHtcbiAgICBhd2FpdCB0aGlzLmluaXQodHJ1ZSwgZmFsc2UsIHVuZGVmaW5lZCwgZmFsc2UpO1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCBmbigpO1xuICAgIH0gZmluYWxseSB7XG4gICAgICBhd2FpdCB0aGlzLmRlc3Ryb3koKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHJlZ2lzdGVyUGx1Z2lucyhzZXJ2ZXI6IEZhc3RpZnlJbnN0YW5jZSwgcGx1Z2luczogU29uYW11U2VydmVyT3B0aW9uc1tcInBsdWdpbnNcIl0pIHtcbiAgICBpZiAoIXBsdWdpbnMpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBjb21wcmVzcyDtlIzrn6zqt7jsnbjsnYAg64uk66W4IO2UjOufrOq3uOyduOuztOuLpCDrqLzsoIAg65Ox66Gd65CY7Ja07JW8IO2VqeuLiOuLpC5cbiAgICBpZiAocGx1Z2lucy5jb21wcmVzcykge1xuICAgICAgY29uc3QgY29tcHJlc3NQbHVnaW4gPSAoYXdhaXQgaW1wb3J0KFwiQGZhc3RpZnkvY29tcHJlc3NcIikpLmRlZmF1bHQ7XG4gICAgICBjb25zdCBkZWZhdWx0T3B0aW9ucyA9IHtcbiAgICAgICAgdGhyZXNob2xkOiAxMDI0LFxuICAgICAgICBlbmNvZGluZ3M6IFtcImJyXCIsIFwiZ3ppcFwiLCBcImRlZmxhdGVcIl0gYXMgKFwiYnJcIiB8IFwiZ3ppcFwiIHwgXCJkZWZsYXRlXCIpW10sXG4gICAgICB9O1xuXG4gICAgICBpZiAocGx1Z2lucy5jb21wcmVzcyA9PT0gdHJ1ZSkge1xuICAgICAgICBzZXJ2ZXIucmVnaXN0ZXIoY29tcHJlc3NQbHVnaW4sIGRlZmF1bHRPcHRpb25zKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHNlcnZlci5yZWdpc3Rlcihjb21wcmVzc1BsdWdpbiwge1xuICAgICAgICAgIC4uLmRlZmF1bHRPcHRpb25zLFxuICAgICAgICAgIC4uLnBsdWdpbnMuY29tcHJlc3MsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IHBsdWdpbnNNb2R1bGVzID0ge1xuICAgICAgY29yczogXCJAZmFzdGlmeS9jb3JzXCIsXG4gICAgICBmb3JtYm9keTogXCJAZmFzdGlmeS9mb3JtYm9keVwiLFxuICAgICAgbXVsdGlwYXJ0OiBcIkBmYXN0aWZ5L211bHRpcGFydFwiLFxuICAgICAgcXM6IFwiZmFzdGlmeS1xc1wiLFxuICAgICAgc3NlOiBcImZhc3RpZnktc3NlLXYyXCIsXG4gICAgICBzdGF0aWM6IFwiQGZhc3RpZnkvc3RhdGljXCIsXG4gICAgfSBhcyBjb25zdDtcblxuICAgIGNvbnN0IHJlZ2lzdGVyUGx1Z2luID0gYXN5bmMgPEsgZXh0ZW5kcyBrZXlvZiBOb25OdWxsYWJsZTx0eXBlb2YgcGx1Z2lucz4+KFxuICAgICAga2V5OiBLLFxuICAgICAgcGx1Z2luTmFtZTogc3RyaW5nLFxuICAgICkgPT4ge1xuICAgICAgY29uc3Qgb3B0aW9uID0gcGx1Z2luc1trZXldO1xuICAgICAgaWYgKCFvcHRpb24pIHJldHVybjtcblxuICAgICAgaWYgKG9wdGlvbiA9PT0gdHJ1ZSkge1xuICAgICAgICBzZXJ2ZXIucmVnaXN0ZXIoKGF3YWl0IGltcG9ydChwbHVnaW5OYW1lKSkuZGVmYXVsdCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzZXJ2ZXIucmVnaXN0ZXIoKGF3YWl0IGltcG9ydChwbHVnaW5OYW1lKSkuZGVmYXVsdCwgb3B0aW9uKTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgZm9yIChjb25zdCBba2V5LCBwbHVnaW5OYW1lXSBvZiBPYmplY3QuZW50cmllcyhwbHVnaW5zTW9kdWxlcykpIHtcbiAgICAgIGF3YWl0IHJlZ2lzdGVyUGx1Z2luKGtleSBhcyBrZXlvZiB0eXBlb2YgcGx1Z2lucywgcGx1Z2luTmFtZSk7XG4gICAgfVxuXG4gICAgaWYgKHBsdWdpbnMud3MpIHtcbiAgICAgIGF3YWl0IHRoaXMuZW5zdXJlV2ViU29ja2V0UGx1Z2luKHNlcnZlcik7XG4gICAgfVxuXG4gICAgaWYgKHBsdWdpbnMuY3VzdG9tKSB7XG4gICAgICBwbHVnaW5zLmN1c3RvbShzZXJ2ZXIpO1xuICAgIH1cbiAgfVxuXG4gIC8vIEBmYXN0aWZ5L3dlYnNvY2tldOydgCBwbHVnaW5zLndz6rCAIOyEpOygleuQnCDqsr3smrDsl5Drp4wg65Ox66Gd7ZWY6rOgLCDqsJnsnYAgc2VydmVy7JeQIOykkeuztSDrk7HroZ3rkJjsp4Ag7JWK64+E66GdIFdlYWtTZXTsnLzroZwg6riw66Gd7ZWoXG4gIHByaXZhdGUgYXN5bmMgZW5zdXJlV2ViU29ja2V0UGx1Z2luKFxuICAgIHNlcnZlcjogRmFzdGlmeUluc3RhbmNlPFNlcnZlciwgSW5jb21pbmdNZXNzYWdlLCBTZXJ2ZXJSZXNwb25zZT4sXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICh0aGlzLndlYnNvY2tldFBsdWdpblNlcnZlcnMuaGFzKHNlcnZlcikpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBwbHVnaW5PcHRpb24gPSB0aGlzLmNvbmZpZy5zZXJ2ZXIucGx1Z2lucz8ud3M7XG4gICAgaWYgKCFwbHVnaW5PcHRpb24pIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCB3ZWJzb2NrZXRQbHVnaW4gPSAoYXdhaXQgaW1wb3J0KFwiQGZhc3RpZnkvd2Vic29ja2V0XCIpKS5kZWZhdWx0O1xuICAgIGNvbnN0IHJlc29sdmVkUGx1Z2luT3B0aW9ucyA9IHJlc29sdmVXZWJTb2NrZXRQbHVnaW5PcHRpb25zKHtcbiAgICAgIHJhd1BsdWdpbk9wdGlvbjogcGx1Z2luT3B0aW9uLFxuICAgIH0pO1xuICAgIGlmIChyZXNvbHZlZFBsdWdpbk9wdGlvbnMpIHtcbiAgICAgIGF3YWl0IHNlcnZlci5yZWdpc3Rlcih3ZWJzb2NrZXRQbHVnaW4sIHJlc29sdmVkUGx1Z2luT3B0aW9ucyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGF3YWl0IHNlcnZlci5yZWdpc3Rlcih3ZWJzb2NrZXRQbHVnaW4pO1xuICAgIH1cblxuICAgIHRoaXMud2Vic29ja2V0UGx1Z2luU2VydmVycy5hZGQoc2VydmVyKTtcbiAgICB0aGlzLndhcm5PblBvdGVudGlhbFdlYlNvY2tldFRpbWVvdXRDb25mbGljdHMoc2VydmVyKTtcbiAgfVxuXG4gIC8vIGhlYXJ0YmVhdCBpbnRlcnZhbOydtCBGYXN0aWZ5IGtlZXBBbGl2ZVRpbWVvdXQg7J207IOB7J2066m0IOyduO2UhOudvOqwgCDrqLzsoIAgaWRsZSDsl7DqsrDsnYQg64GK7J2EIOyImCDsnojslrQg6rK96rOg66eMIOuCqOq4sOqzoCDrhJjslrTqsJBcbiAgcHJpdmF0ZSB3YXJuT25Qb3RlbnRpYWxXZWJTb2NrZXRUaW1lb3V0Q29uZmxpY3RzKFxuICAgIHNlcnZlcjogRmFzdGlmeUluc3RhbmNlPFNlcnZlciwgSW5jb21pbmdNZXNzYWdlLCBTZXJ2ZXJSZXNwb25zZT4sXG4gICk6IHZvaWQge1xuICAgIGNvbnN0IGhlYXJ0YmVhdHMgPSB0aGlzLnN5bmNlci5hcGlzXG4gICAgICAubWFwKChhcGkpID0+IGFwaS53ZWJzb2NrZXRPcHRpb25zPy5oZWFydGJlYXQgPz8gMzAwMDApXG4gICAgICAuZmlsdGVyKChoZWFydGJlYXQpID0+IGhlYXJ0YmVhdCA+IDApO1xuXG4gICAgaWYgKGhlYXJ0YmVhdHMubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3Qga2VlcEFsaXZlVGltZW91dCA9IHRoaXMuY29uZmlnLnNlcnZlci5mYXN0aWZ5Py5rZWVwQWxpdmVUaW1lb3V0O1xuICAgIGlmICgha2VlcEFsaXZlVGltZW91dCB8fCBrZWVwQWxpdmVUaW1lb3V0IDw9IDApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBsYXJnZXN0SGVhcnRiZWF0ID0gTWF0aC5tYXgoLi4uaGVhcnRiZWF0cyk7XG4gICAgaWYgKGxhcmdlc3RIZWFydGJlYXQgPj0ga2VlcEFsaXZlVGltZW91dCkge1xuICAgICAgc2VydmVyLmxvZy53YXJuKFxuICAgICAgICB7XG4gICAgICAgICAga2VlcEFsaXZlVGltZW91dCxcbiAgICAgICAgICBsYXJnZXN0SGVhcnRiZWF0LFxuICAgICAgICB9LFxuICAgICAgICBcIldlYlNvY2tldCBoZWFydGJlYXQgaXMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIGtlZXBBbGl2ZVRpbWVvdXQ7IGFsaWduIGluZnJhc3RydWN0dXJlIGlkbGUgdGltZW91dHMgdG8gYXZvaWQgdW5leHBlY3RlZCBkaXNjb25uZWN0cy5cIixcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIGJldHRlci1hdXRoIOudvOyasO2KuOulvCDrk7HroZ3tlanri4jri6QuXG4gICAqIC9hcGkvYXV0aC8qIOqyveuhnOuhnCDsnbjspp0gQVBJ6rCAIOyekOuPmSDrk7HroZ3rkKnri4jri6QuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIHJlZ2lzdGVyQmV0dGVyQXV0aChcbiAgICBzZXJ2ZXI6IEZhc3RpZnlJbnN0YW5jZSxcbiAgICBvcHRpb25zOiBOb25OdWxsYWJsZTxTb25hbXVTZXJ2ZXJPcHRpb25zW1wiYXV0aFwiXT4sXG4gICkge1xuICAgIGlmICghb3B0aW9ucykgcmV0dXJuO1xuXG4gICAgY29uc3QgYmFzZVBhdGggPSBvcHRpb25zLmJhc2VQYXRoID8/IFwiL2FwaS9hdXRoXCI7XG5cbiAgICAvLyBiZXR0ZXItYXV0aCDrnbzsmrDtirgg65Ox66GdXG4gICAgc2VydmVyLnJvdXRlKHtcbiAgICAgIG1ldGhvZDogW1wiR0VUXCIsIFwiUE9TVFwiXSxcbiAgICAgIHVybDogYCR7YmFzZVBhdGh9LypgLFxuICAgICAgaGFuZGxlcjogYXN5bmMgKHJlcXVlc3QsIHJlcGx5KSA9PiB7XG4gICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgdGhpcy5hdXRoLmhhbmRsZXIoXG4gICAgICAgICAgY3JlYXRlQmV0dGVyQXV0aFJlcXVlc3QocmVxdWVzdCwgb3B0aW9ucy5hZHZhbmNlZD8uaXBBZGRyZXNzPy5pcEFkZHJlc3NIZWFkZXJzKSxcbiAgICAgICAgKTtcblxuICAgICAgICByZXBseS5zdGF0dXMocmVzcG9uc2Uuc3RhdHVzKTtcbiAgICAgICAgcmVzcG9uc2UuaGVhZGVycy5mb3JFYWNoKCh2YWx1ZTogc3RyaW5nLCBrZXk6IHN0cmluZykgPT4ge1xuICAgICAgICAgIHJlcGx5LmhlYWRlcihrZXksIHZhbHVlKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiByZXBseS5zZW5kKHJlc3BvbnNlLmJvZHkgPyBhd2FpdCByZXNwb25zZS50ZXh0KCkgOiBudWxsKTtcbiAgICAgIH0sXG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHByaW50U3RhcnR1cFN1bW1hcnkoKSB7XG4gICAgY29uc3QgY2hhbGsgPSAoYXdhaXQgaW1wb3J0KFwiY2hhbGtcIikpLmRlZmF1bHQ7XG4gICAgY29uc3QgYWN0aXZlUHJlc2V0ID0gZ2V0U29uYW11RW52aXJvbm1lbnQoKTtcblxuICAgIGNvbnN0IGRpbSA9IChtc2c6IHN0cmluZykgPT4gY29uc29sZS5sb2coY2hhbGsuZGltKGDinJMgJHttc2d9YCkpO1xuICAgIGNvbnN0IGdyZWVuID0gKG1zZzogc3RyaW5nKSA9PiBjb25zb2xlLmxvZyhjaGFsay5ncmVlbihg4pyTICR7bXNnfWApKTtcblxuICAgIGRpbShgQ29uZmlnIGxvYWRlZCR7Zm9ybWF0VGltZSh0aGlzLl9jb25maWdFbGFwc2VkKX1gKTtcblxuICAgIC8vIERCIHByZXNldCDrqqnroZ1cbiAgICBncmVlbihcIkRCXCIpO1xuICAgIGNvbnN0IHsgaXNMb2NhbCB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vdXRpbHMvY29udHJvbGxlclwiKTtcbiAgICBjb25zdCBwcmVzZXROYW1lcyA9IE9iamVjdC5rZXlzKHRoaXMuZGJDb25maWcpIGFzIChrZXlvZiBTb25hbXVEQkNvbmZpZylbXTtcbiAgICBjb25zdCBtYXhMZW4gPSBNYXRoLm1heCguLi5wcmVzZXROYW1lcy5tYXAoKG4pID0+IG4ubGVuZ3RoKSk7XG4gICAgZm9yIChjb25zdCBuYW1lIG9mIHByZXNldE5hbWVzKSB7XG4gICAgICBjb25zdCBjb25uID0gdGhpcy5kYkNvbmZpZ1tuYW1lXS5jb25uZWN0aW9uIGFzXG4gICAgICAgIHwgeyBob3N0Pzogc3RyaW5nOyBwb3J0PzogbnVtYmVyOyBkYXRhYmFzZT86IHN0cmluZyB9XG4gICAgICAgIHwgdW5kZWZpbmVkO1xuICAgICAgY29uc3QgaG9zdCA9IGNvbm4/Lmhvc3QgPz8gXCJsb2NhbGhvc3RcIjtcbiAgICAgIGNvbnN0IGFkZHIgPSBgQCAke2hvc3R9OiR7Y29ubj8ucG9ydCA/PyA1NDMyfS8ke2Nvbm4/LmRhdGFiYXNlID8/IFwiKHVua25vd24pXCJ9YDtcbiAgICAgIGNvbnN0IHBhZGRlZCA9IG5hbWUucGFkRW5kKG1heExlbik7XG4gICAgICBjb25zdCByZW1vdGVUYWcgPSBpc0xvY2FsKCkgJiYgIWlzTG9jYWxIb3N0KGhvc3QpID8gY2hhbGsueWVsbG93KGAgXFx1MjZhMCByZW1vdGVgKSA6IFwiXCI7XG5cbiAgICAgIGlmIChuYW1lID09PSBhY3RpdmVQcmVzZXQpIHtcbiAgICAgICAgY29uc29sZS5sb2coY2hhbGsuZ3JlZW4oYCAgXFx1MjViOCAke3BhZGRlZH0gJHthZGRyfWApICsgcmVtb3RlVGFnKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnNvbGUubG9nKGNoYWxrLmRpbShgICAgICR7cGFkZGVkfSAke2FkZHJ9YCkgKyByZW1vdGVUYWcpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0aGlzLmNvbmZpZy5zZXJ2ZXIuYXV0aCkge1xuICAgICAgY29uc3QgYmFzZVBhdGggPSB0aGlzLmNvbmZpZy5zZXJ2ZXIuYXV0aC5iYXNlUGF0aCA/PyBcIi9hcGkvYXV0aFwiO1xuICAgICAgZGltKGBBdXRoOiBiZXR0ZXItYXV0aCBhdCAke2Jhc2VQYXRofS8qYCk7XG4gICAgfVxuICAgIGlmICh0aGlzLmNvbmZpZy5hcGkudGltZXpvbmUpIHtcbiAgICAgIGRpbShgVGltZXpvbmU6ICR7dGhpcy5jb25maWcuYXBpLnRpbWV6b25lfWApO1xuICAgIH1cbiAgICBncmVlbihgU29uYW11IHJlYWR5JHtmb3JtYXRUaW1lKHRoaXMuX2luaXRFbGFwc2VkKX1gKTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgaW5pdGlhbGl6ZUNhY2hlKGNvbmZpZzogQ2FjaGVDb25maWcgfCB1bmRlZmluZWQsIGZvclRlc3Rpbmc6IGJvb2xlYW4pIHtcbiAgICBjb25zdCB7IHNldENhY2hlTWFuYWdlclJlZiB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vY2FjaGUvZGVjb3JhdG9yXCIpO1xuXG4gICAgLy8g7YWM7Iqk7Yq4IO2ZmOqyveyXkOyEnCDrqZTrqqjrpqwg65Oc65287J2067KEIOyekOuPmSDsgqzsmqlcbiAgICBpZiAoZm9yVGVzdGluZykge1xuICAgICAgY29uc3QgeyBjcmVhdGVUZXN0Q2FjaGVNYW5hZ2VyIH0gPSBhd2FpdCBpbXBvcnQoXCIuLi9jYWNoZS9jYWNoZS1tYW5hZ2VyXCIpO1xuICAgICAgdGhpcy5fY2FjaGUgPSBjcmVhdGVUZXN0Q2FjaGVNYW5hZ2VyKCk7XG4gICAgICBzZXRDYWNoZU1hbmFnZXJSZWYodGhpcy5fY2FjaGUpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIOyEpOygleydtCDsl4bsnLzrqbQg7LqQ7IucIOu5hO2ZnOyEse2ZlFxuICAgIGlmICghY29uZmlnKSB7XG4gICAgICBzZXRDYWNoZU1hbmFnZXJSZWYobnVsbCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8g7ISk7KCV7JeQIOuUsOudvCBDYWNoZU1hbmFnZXIg7IOd7ISxXG4gICAgY29uc3QgeyBjcmVhdGVDYWNoZU1hbmFnZXIgfSA9IGF3YWl0IGltcG9ydChcIi4uL2NhY2hlL2NhY2hlLW1hbmFnZXJcIik7XG4gICAgdGhpcy5fY2FjaGUgPSBjcmVhdGVDYWNoZU1hbmFnZXIoY29uZmlnKTtcbiAgICBzZXRDYWNoZU1hbmFnZXJSZWYodGhpcy5fY2FjaGUpO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBpbml0aWFsaXplV29ya2Zsb3dzKG9wdGlvbnM6IFNvbmFtdVRhc2tPcHRpb25zIHwgdW5kZWZpbmVkKSB7XG4gICAgY29uc3QgeyBXb3JrZmxvd01hbmFnZXIgfSA9IGF3YWl0IGltcG9ydChcIi4uL3Rhc2tzL3dvcmtmbG93LW1hbmFnZXJcIik7XG4gICAgLy8gTk9URTogQHNvbmFtdS1raXQvdGFza3Mg7JWI7JeQ7ISgIGtuZXggY29uZmln66W8IOyImOygle2VmOq4sCDrlYzrrLjsl5AgY29ubmVjdGlvbuydtCDslYTri4wgY29uZmlnIOynuOuhnCDrs7Trg4Xri4jri6QuXG4gICAgdGhpcy5fd29ya2Zsb3dzID0gbmV3IFdvcmtmbG93TWFuYWdlcihEQi5nZXREQkNvbmZpZyhcIndcIikpO1xuICAgIGlmICghb3B0aW9ucykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGVuYWJsZVdvcmtlciA9IG9wdGlvbnMuZW5hYmxlV29ya2VyID8/IGlzRGFlbW9uU2VydmVyKCk7XG4gICAgY29uc3QgZGVmYXVsdFdvcmtlck9wdGlvbnMgPSB7XG4gICAgICBjb25jdXJyZW5jeTogb3MuY3B1cygpLmxlbmd0aCAtIDEsXG4gICAgICB1c2VQdWJTdWI6IHRydWUsXG4gICAgICBsaXN0ZW5EZWxheTogNTAwLFxuICAgIH07XG5cbiAgICBpZiAoZW5hYmxlV29ya2VyKSB7XG4gICAgICB0aGlzLndvcmtmbG93cy5zZXR1cFdvcmtlcih7XG4gICAgICAgIC4uLmRlZmF1bHRXb3JrZXJPcHRpb25zLFxuICAgICAgICAuLi5vcHRpb25zLndvcmtlck9wdGlvbnMsXG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGJvb3Qoc2VydmVyOiBGYXN0aWZ5SW5zdGFuY2UsIG9wdGlvbnM6IFNvbmFtdVNlcnZlck9wdGlvbnMpIHtcbiAgICBjb25zdCBwb3J0ID0gb3B0aW9ucy5saXN0ZW4/LnBvcnQgPz8gMzAwMDtcbiAgICBjb25zdCBob3N0ID0gb3B0aW9ucy5saXN0ZW4/Lmhvc3QgPz8gXCJsb2NhbGhvc3RcIjtcblxuICAgIHNlcnZlci5hZGRIb29rKFwib25DbG9zZVwiLCBhc3luYyAoKSA9PiB7XG4gICAgICBhd2FpdCBvcHRpb25zLmxpZmVjeWNsZT8ub25TaHV0ZG93bj8uKHNlcnZlcik7XG4gICAgICBhd2FpdCB0aGlzLndvcmtmbG93cy5kZXN0cm95KCk7XG4gICAgICBhd2FpdCB0aGlzLmRlc3Ryb3koKTtcbiAgICB9KTtcblxuICAgIGNvbnN0IHNodXRkb3duID0gYXN5bmMgKCkgPT4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgc2VydmVyLmNsb3NlKCk7XG4gICAgICAgIHByb2Nlc3MuZXhpdCgwKTtcbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICBjb25zb2xlLmVycm9yKFwiRXJyb3IgZHVyaW5nIHNodXRkb3duOlwiLCBlcnIpO1xuICAgICAgICBwcm9jZXNzLmV4aXQoMSk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIHByb2Nlc3Mub24oXCJTSUdJTlRcIiwgc2h1dGRvd24pO1xuICAgIHByb2Nlc3Mub24oXCJTSUdURVJNXCIsIHNodXRkb3duKTtcblxuICAgIGlmIChvcHRpb25zLmxpZmVjeWNsZT8ub25FcnJvcikge1xuICAgICAgc2VydmVyLnNldEVycm9ySGFuZGxlcihvcHRpb25zLmxpZmVjeWNsZT8ub25FcnJvcik7XG4gICAgfVxuXG4gICAgc2VydmVyXG4gICAgICAubGlzdGVuKHsgcG9ydCwgaG9zdCB9KVxuICAgICAgLnRoZW4oYXN5bmMgKCkgPT4ge1xuICAgICAgICBhd2FpdCB0aGlzLndvcmtmbG93cy5zdGFydFdvcmtlcigpO1xuICAgICAgICBhd2FpdCBvcHRpb25zLmxpZmVjeWNsZT8ub25TdGFydD8uKHNlcnZlcik7XG4gICAgICB9KVxuICAgICAgLmNhdGNoKGFzeW5jIChlcnIpID0+IHtcbiAgICAgICAgY29uc3QgY2hhbGsgPSAoYXdhaXQgaW1wb3J0KFwiY2hhbGtcIikpLmRlZmF1bHQ7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoY2hhbGsucmVkKFwiRmFpbGVkIHRvIHN0YXJ0IHNlcnZlcjpcIiwgZXJyKSk7XG4gICAgICAgIGF3YWl0IHNodXRkb3duKCk7XG4gICAgICB9KTtcbiAgfVxuXG4gIGFzeW5jIGRlc3Ryb3koKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgeyBCYXNlTW9kZWwgfSA9IGF3YWl0IGltcG9ydChcIi4uL2RhdGFiYXNlL2Jhc2UtbW9kZWxcIik7XG4gICAgLy8g66i87KCAIOyymOumrO2VtOyVvO2VqC5cbiAgICBhd2FpdCBCYXNlTW9kZWwuZGVzdHJveSgpO1xuICAgIC8vIFdlYlNvY2tldCBzaHV0ZG93biBmaXJzdCB0byBmbHVzaCB0ZWxlbWV0cnlcbiAgICBpZiAodGhpcy5fd2Vic29ja2V0UnVudGltZSkge1xuICAgICAgYXdhaXQgdGhpcy5fd2Vic29ja2V0UnVudGltZS5zaHV0ZG93bigpO1xuICAgIH1cbiAgICB0aGlzLl93ZWJzb2NrZXRSdW50aW1lID0gbnVsbDtcbiAgICAvLyBUaGVuIHNodXQgZG93biByZW1haW5pbmcgcmVzb3VyY2VzIGluIHBhcmFsbGVsXG4gICAgYXdhaXQgUHJvbWlzZS5hbGxTZXR0bGVkKFtcbiAgICAgIHRoaXMuX3dvcmtmbG93cz8uZGVzdHJveSgpID8/IFByb21pc2UucmVzb2x2ZSgpLFxuICAgICAgdGhpcy5fY2FjaGU/LmRpc2Nvbm5lY3QoKSA/PyBQcm9taXNlLnJlc29sdmUoKSxcbiAgICAgIHRoaXMuX2RldlZpdGVzdE1hbmFnZXI/LnNodXRkb3duKCkgPz8gUHJvbWlzZS5yZXNvbHZlKCksXG4gICAgICB0aGlzLndhdGNoZXI/LmNsb3NlKCkgPz8gUHJvbWlzZS5yZXNvbHZlKCksXG4gICAgXSk7XG4gICAgLy8gTG9nVGFwZSBkaXNwb3NlIGFmdGVyIFdTIHNodXRkb3duIHNvIHRlbGVtZXRyeSByZWNvcmRzIGFyZSBmbHVzaGVkIGZpcnN0XG4gICAgYXdhaXQgbG9ndGFwZURpc3Bvc2UoKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBnZXRXZWJTb2NrZXRUZWxlbWV0cnlDb250ZXh0KFxuICB3czogV2ViU29ja2V0Q29ubmVjdGlvbjxXZWJTb2NrZXRFdmVudE1hcCwgV2ViU29ja2V0RXZlbnRNYXA+LFxuKTogV2ViU29ja2V0VGVsZW1ldHJ5Q29ubmVjdGlvbkNvbnRleHQge1xuICBpZiAoIWlzVGVsZW1ldHJ5Q29udGV4dFByb3ZpZGVyKHdzKSkge1xuICAgIHJldHVybiB7fTtcbiAgfVxuXG4gIHJldHVybiB3cy5nZXRUZWxlbWV0cnlDb250ZXh0KCk7XG59XG5cbmZ1bmN0aW9uIGlzVGVsZW1ldHJ5Q29udGV4dFByb3ZpZGVyKFxuICB3czogV2ViU29ja2V0Q29ubmVjdGlvbjxXZWJTb2NrZXRFdmVudE1hcCwgV2ViU29ja2V0RXZlbnRNYXA+LFxuKTogd3MgaXMgV2ViU29ja2V0Q29ubmVjdGlvbjxXZWJTb2NrZXRFdmVudE1hcCwgV2ViU29ja2V0RXZlbnRNYXA+ICYgVGVsZW1ldHJ5Q29udGV4dFByb3ZpZGVyIHtcbiAgcmV0dXJuIFwiZ2V0VGVsZW1ldHJ5Q29udGV4dFwiIGluIHdzICYmIHR5cGVvZiB3cy5nZXRUZWxlbWV0cnlDb250ZXh0ID09PSBcImZ1bmN0aW9uXCI7XG59XG5cbmV4cG9ydCBjb25zdCBTb25hbXUgPSBuZXcgU29uYW11Q2xhc3MoKTtcblxuLyoqXG4gKiBzdHJlYW0g66qo65Oc7JeQ7IScIO2CpCDsg53shLEg7ZWo7IiY6rCAIOyngOygleuQmOyngCDslYrslZjsnYQg65WMIOyCrOyaqe2VmOuKlCDquLDrs7gg7ZWo7IiY7J6F64uI64ukLlxuICovXG5mdW5jdGlvbiBkZWZhdWx0S2V5R2VuZXJhdG9yKGZpbGU6IHsgZmlsZW5hbWU6IHN0cmluZzsgbWltZXR5cGU6IHN0cmluZyB9KTogc3RyaW5nIHtcbiAgY29uc3QgZXh0ID0gbWltZS5leHRlbnNpb24oZmlsZS5taW1ldHlwZSkgfHwgXCJiaW5cIjtcbiAgY29uc3QgdGltZXN0YW1wID0gRGF0ZS5ub3coKTtcbiAgY29uc3QgcmFuZG9tID0gTWF0aC5yYW5kb20oKS50b1N0cmluZygzNikuc2xpY2UoMiwgOCk7XG4gIHJldHVybiBgdXBsb2Fkcy8ke3RpbWVzdGFtcH0tJHtyYW5kb219LiR7ZXh0fWA7XG59XG5cbmZ1bmN0aW9uIGZvcm1hdFRpbWUobXM6IG51bWJlcik6IHN0cmluZyB7XG4gIGNvbnN0IGZvcm1hdHRlZCA9IG1zID49IDEwMDAgPyBgJHsobXMgLyAxMDAwKS50b0ZpeGVkKDIpfXNgIDogYCR7TWF0aC5yb3VuZChtcyl9bXNgO1xuICByZXR1cm4gYCAoJHtmb3JtYXR0ZWR9KWA7XG59XG5cbmNvbnN0IExPQ0FMX0hPU1RTID0gbmV3IFNldChbXCJsb2NhbGhvc3RcIiwgXCIxMjcuMC4wLjFcIiwgXCIwLjAuMC4wXCIsIFwiOjoxXCJdKTtcbmZ1bmN0aW9uIGlzTG9jYWxIb3N0KGhvc3Q6IHN0cmluZyk6IGJvb2xlYW4ge1xuICByZXR1cm4gTE9DQUxfSE9TVFMuaGFzKGhvc3QpIHx8IGhvc3QuZW5kc1dpdGgoXCIubG9jYWxcIik7XG59XG5cbi8vIGAuZXZlcnkoKWDqsIAg7LKrIGd1YXJkIOydtO2bhCDsiJztmozrpbwg66mI7LaU64qUIOusuOygnOqwgCDsnojslrQgYGZvci4uLm9mYOuhnCDrqqjrk6AgZ3VhcmTrpbwg7Iic7ISc64yA66GcIOyLpO2Wie2VmOuPhOuhnSDqs6DsoJXtlahcbmZ1bmN0aW9uIHJ1bkd1YXJkcyh7XG4gIGd1YXJkcyxcbiAgY29uZmlnLFxuICByZXF1ZXN0LFxuICBhcGksXG59OiB7XG4gIGd1YXJkczogRXh0ZW5kZWRBcGlbXCJvcHRpb25zXCJdW1wiZ3VhcmRzXCJdIHwgdW5kZWZpbmVkO1xuICBjb25maWc6IFBpY2s8U29uYW11RmFzdGlmeUNvbmZpZywgXCJndWFyZEhhbmRsZXJcIj47XG4gIHJlcXVlc3Q6IEZhc3RpZnlSZXF1ZXN0O1xuICBhcGk6IEV4dGVuZGVkQXBpO1xufSk6IHZvaWQge1xuICBmb3IgKGNvbnN0IGd1YXJkIG9mIGd1YXJkcyA/PyBbXSkge1xuICAgIGNvbmZpZy5ndWFyZEhhbmRsZXIoZ3VhcmQsIHJlcXVlc3QsIGFwaSk7XG4gIH1cbn1cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBZzdEQSxTQUFTLDZCQUNQLElBQ3FDO0NBQ3JDLElBQUksQ0FBQywyQkFBMkIsRUFBRSxHQUNoQyxPQUFPLENBQUM7Q0FHVixPQUFPLEdBQUcsb0JBQW9CO0FBQ2hDO0FBRUEsU0FBUywyQkFDUCxJQUM0RjtDQUM1RixPQUFPLHlCQUF5QixNQUFNLE9BQU8sR0FBRyx3QkFBd0I7QUFDMUU7Ozs7QUFPQSxTQUFTLG9CQUFvQixNQUFzRDtDQUNqRixNQUFNLE1BQU0sS0FBSyxVQUFVLEtBQUssUUFBUSxLQUFLO0NBRzdDLE9BQU8sV0FGVyxLQUFLLElBRUwsRUFBVSxHQURiLEtBQUssT0FBTyxDQUFDLENBQUMsU0FBUyxFQUFFLENBQUMsQ0FBQyxNQUFNLEdBQUcsQ0FDcEIsRUFBTyxHQUFHO0FBQzNDO0FBRUEsU0FBUyxXQUFXLElBQW9CO0NBRXRDLE9BQU8sS0FEVyxNQUFNLE1BQU8sSUFBSSxLQUFLLElBQUEsQ0FBTSxRQUFRLENBQUMsRUFBRSxLQUFLLEdBQUcsS0FBSyxNQUFNLEVBQUUsRUFBRSxJQUMxRDtBQUN4QjtBQUdBLFNBQVMsWUFBWSxNQUF1QjtDQUMxQyxPQUFPLFlBQVksSUFBSSxJQUFJLEtBQUssS0FBSyxTQUFTLFFBQVE7QUFDeEQ7QUFHQSxTQUFTLFVBQVUsRUFDakIsUUFDQSxRQUNBLFNBQ0EsT0FNTztDQUNQLEtBQUssTUFB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
|
|
1410
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic29uYW11LmpzIiwibmFtZXMiOlsibWltZUxvb2t1cCIsImxvZ3RhcGVEaXNwb3NlIl0sInNvdXJjZXMiOlsiLi4vLi4vc3JjL2FwaS9zb25hbXUudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQXN5bmNMb2NhbFN0b3JhZ2UgfSBmcm9tIFwiYXN5bmNfaG9va3NcIjtcbmltcG9ydCBmcyBmcm9tIFwiZnMvcHJvbWlzZXNcIjtcbmltcG9ydCB7IHR5cGUgSW5jb21pbmdNZXNzYWdlLCB0eXBlIFNlcnZlciwgdHlwZSBTZXJ2ZXJSZXNwb25zZSB9IGZyb20gXCJodHRwXCI7XG5pbXBvcnQgb3MgZnJvbSBcIm9zXCI7XG5pbXBvcnQgcGF0aCBmcm9tIFwicGF0aFwiO1xuXG5pbXBvcnQgXCJAZmFzdGlmeS93ZWJzb2NrZXRcIjtcbmltcG9ydCB7IGRpc3Bvc2UgYXMgbG9ndGFwZURpc3Bvc2UgfSBmcm9tIFwiQGxvZ3RhcGUvbG9ndGFwZVwiO1xuaW1wb3J0IHsgdHlwZSBBdXRoLCB0eXBlIEJldHRlckF1dGhPcHRpb25zIH0gZnJvbSBcImJldHRlci1hdXRoXCI7XG5pbXBvcnQgY2hhbGsgZnJvbSBcImNoYWxrXCI7XG5pbXBvcnQgeyB0eXBlIEZTV2F0Y2hlciB9IGZyb20gXCJjaG9raWRhclwiO1xuaW1wb3J0IHsgdHlwZSBGYXN0aWZ5SW5zdGFuY2UsIHR5cGUgRmFzdGlmeVJlcGx5LCB0eXBlIEZhc3RpZnlSZXF1ZXN0IH0gZnJvbSBcImZhc3RpZnlcIjtcbmltcG9ydCBtaW1lLCB7IGxvb2t1cCBhcyBtaW1lTG9va3VwIH0gZnJvbSBcIm1pbWUtdHlwZXNcIjtcbmltcG9ydCB7IHR5cGUgV2ViU29ja2V0IH0gZnJvbSBcIndzXCI7XG5pbXBvcnQgeyB0eXBlIFpvZE9iamVjdCB9IGZyb20gXCJ6b2RcIjtcblxuaW1wb3J0IHsgQkFTRV9GSUVMRF9NQVBQSU5HUyB9IGZyb20gXCIuLi9hdXRoL2JldHRlci1hdXRoLWVudGl0aWVzXCI7XG5pbXBvcnQgeyBjcmVhdGVCZXR0ZXJBdXRoUmVxdWVzdCB9IGZyb20gXCIuLi9hdXRoL2JldHRlci1hdXRoLXJlcXVlc3RcIjtcbmltcG9ydCB7IGFwcGx5Q2FjaGVIZWFkZXJzLCBDYWNoZVByZXNldHMgfSBmcm9tIFwiLi4vY2FjaGUtY29udHJvbC9jYWNoZS1jb250cm9sXCI7XG5pbXBvcnQgeyB0eXBlIENhY2hlQ29udHJvbENvbmZpZywgdHlwZSBDYWNoZUNvbnRyb2xSZXF1ZXN0IH0gZnJvbSBcIi4uL2NhY2hlLWNvbnRyb2wvdHlwZXNcIjtcbmltcG9ydCB7IHR5cGUgQ2FjaGVDb25maWcsIHR5cGUgQ2FjaGVNYW5hZ2VyIH0gZnJvbSBcIi4uL2NhY2hlL3R5cGVzXCI7XG5pbXBvcnQgeyB0b0Zhc3RpZnlDb21wcmVzc09wdGlvbiB9IGZyb20gXCIuLi9jb21wcmVzcy9jb21wcmVzc1wiO1xuaW1wb3J0IHsgdHlwZSBDb21wcmVzc09wdGlvbnMgfSBmcm9tIFwiLi4vY29tcHJlc3MvdHlwZXNcIjtcbmltcG9ydCB7IERCIH0gZnJvbSBcIi4uL2RhdGFiYXNlL2RiXCI7XG5pbXBvcnQgeyB0eXBlIFNvbmFtdURCQ29uZmlnIH0gZnJvbSBcIi4uL2RhdGFiYXNlL2RiXCI7XG5pbXBvcnQgeyBTRCwgc2V0U0RDb25maWcgfSBmcm9tIFwiLi4vZGljdC9zZFwiO1xuaW1wb3J0IHsgdHlwZSBMb2NhbGl6ZWRTdHJpbmcgfSBmcm9tIFwiLi4vZGljdC90eXBlc1wiO1xuaW1wb3J0IHsgZ2V0U29uYW11RW52aXJvbm1lbnQsIHJlYWRBbGxFbnZpcm9ubWVudFNuYXBzaG90cyB9IGZyb20gXCIuLi9lbnZcIjtcbmltcG9ydCB7IE5vdEZvdW5kRXhjZXB0aW9uIH0gZnJvbSBcIi4uL2V4Y2VwdGlvbnMvc28tZXhjZXB0aW9uc1wiO1xuaW1wb3J0IHsgcnVudGltZVR5cGVPZiB9IGZyb20gXCIuLi9ydW50aW1lLXR5cGVcIjtcbmltcG9ydCB7IEJ1ZmZlcmVkRmlsZSB9IGZyb20gXCIuLi9zdG9yYWdlL2J1ZmZlcmVkLWZpbGVcIjtcbmltcG9ydCB7IHR5cGUgU3RvcmFnZU1hbmFnZXIgfSBmcm9tIFwiLi4vc3RvcmFnZS9zdG9yYWdlLW1hbmFnZXJcIjtcbmltcG9ydCB7IHR5cGUgS2V5R2VuZXJhdG9yIH0gZnJvbSBcIi4uL3N0b3JhZ2UvdHlwZXNcIjtcbmltcG9ydCB7IFVwbG9hZGVkRmlsZSB9IGZyb20gXCIuLi9zdG9yYWdlL3VwbG9hZGVkLWZpbGVcIjtcbmltcG9ydCB7IGNyZWF0ZU1vY2tTU0VGYWN0b3J5IH0gZnJvbSBcIi4uL3N0cmVhbS9zc2VcIjtcbmltcG9ydCB7XG4gIHR5cGUgQW55V2ViU29ja2V0Q29ubmVjdGlvbixcbiAgV2ViU29ja2V0UnVudGltZSxcbiAgdHlwZSBXZWJTb2NrZXRDb25uZWN0aW9uLFxufSBmcm9tIFwiLi4vc3RyZWFtL3dzXCI7XG5pbXBvcnQge1xuICB0eXBlIFRlbGVtZXRyeUNvbnRleHRQcm92aWRlcixcbiAgdHlwZSBXZWJTb2NrZXRUZWxlbWV0cnlDb25uZWN0aW9uQ29udGV4dCxcbn0gZnJvbSBcIi4uL3N0cmVhbS93cy10ZWxlbWV0cnlcIjtcbmltcG9ydCB7IHR5cGUgTG9hZGVkTW9kZWxzIH0gZnJvbSBcIi4uL3N5bmNlci9tb2R1bGUtbG9hZGVyXCI7XG5pbXBvcnQgeyB0eXBlIFN5bmNlciB9IGZyb20gXCIuLi9zeW5jZXIvc3luY2VyXCI7XG5pbXBvcnQgeyB0eXBlIFdvcmtmbG93TWFuYWdlciB9IGZyb20gXCIuLi90YXNrcy93b3JrZmxvdy1tYW5hZ2VyXCI7XG5pbXBvcnQgeyB0eXBlIERldlZpdGVzdE1hbmFnZXIgfSBmcm9tIFwiLi4vdGVzdGluZy9kZXYtdml0ZXN0LW1hbmFnZXJcIjtcbmltcG9ydCB7IHR5cGUgU29uYW11RmFzdGlmeUNvbmZpZyB9IGZyb20gXCIuLi90eXBlcy90eXBlc1wiO1xuaW1wb3J0IHsgY2VudGVyVGV4dCB9IGZyb20gXCIuLi91dGlscy9jb25zb2xlLXV0aWxcIjtcbmltcG9ydCB7IGlzRGFlbW9uU2VydmVyIH0gZnJvbSBcIi4uL3V0aWxzL2NvbnRyb2xsZXJcIjtcbmltcG9ydCB7IGV4aXN0cywgZmlsZUV4aXN0cyB9IGZyb20gXCIuLi91dGlscy9mcy11dGlsc1wiO1xuaW1wb3J0IHsgdHlwZSBBYnNvbHV0ZVBhdGggfSBmcm9tIFwiLi4vdXRpbHMvcGF0aC11dGlsc1wiO1xuaW1wb3J0IHtcbiAgaXNCaWdJbnRWYWx1ZSxcbiAgaXNGdW5jdGlvblZhbHVlLFxuICBpc051bWJlclZhbHVlLFxuICBpc09iamVjdFZhbHVlLFxuICBpc1N0cmluZ1ZhbHVlLFxuICBpc1N5bWJvbFZhbHVlLFxufSBmcm9tIFwiLi4vdXRpbHMvcnVudGltZS12YWx1ZVwiO1xuaW1wb3J0IHsgY29udmVydEZhc3RpZnlIZWFkZXJzVG9TdGFuZGFyZCwgbWVyZ2UgfSBmcm9tIFwiLi4vdXRpbHMvdXRpbHNcIjtcbmltcG9ydCB7XG4gIG5vcm1hbGl6ZVpvZENvbXBpbGVyUG9saWN5LFxuICB0eXBlIFNvbmFtdUNvbmZpZyxcbiAgdHlwZSBTb25hbXVTZXJ2ZXJPcHRpb25zLFxuICB0eXBlIFNvbmFtdVRhc2tPcHRpb25zLFxufSBmcm9tIFwiLi9jb25maWdcIjtcbmltcG9ydCB7IHR5cGUgQ29udGV4dCwgdHlwZSBSdW50aW1lQ29udGV4dCwgdHlwZSBXZWJTb2NrZXRDb250ZXh0IH0gZnJvbSBcIi4vY29udGV4dFwiO1xuaW1wb3J0IHsgdHlwZSBFeHRlbmRlZEFwaSB9IGZyb20gXCIuL2RlY29yYXRvcnNcIjtcbmltcG9ydCB7XG4gIGFzc2VydEh0dHBWYWxpZGF0b3JSZWdpc3RyeSxcbiAgY3JlYXRlSHR0cFZhbGlkYXRvcixcbiAgZ2V0SHR0cFZhbGlkYXRvclJvdXRlS2V5LFxuICB0eXBlIEh0dHBWYWxpZGF0b3IsXG4gIHR5cGUgSHR0cFZhbGlkYXRvclJlZ2lzdHJ5LFxufSBmcm9tIFwiLi9odHRwLXZhbGlkYXRvclwiO1xuaW1wb3J0IHsgZ2V0U2VjcmV0cyB9IGZyb20gXCIuL3NlY3JldFwiO1xuaW1wb3J0IHsgdHlwZSBTb25hbXVTZWNyZXRzIH0gZnJvbSBcIi4vc2VjcmV0XCI7XG5pbXBvcnQge1xuICBjcmVhdGVXZWJTb2NrZXRSZXBseVN0dWIsXG4gIHJlc29sdmVXZWJTb2NrZXRDbG9zZURlc2NyaXB0b3IsXG4gIHJlc29sdmVXZWJTb2NrZXRQbHVnaW5PcHRpb25zLFxuICByZXNvbHZlSW50ZWdyYXRlZFZpdGVIbXJPcHRpb25zLFxufSBmcm9tIFwiLi93ZWJzb2NrZXQtaGVscGVyc1wiO1xuXG5leHBvcnQge1xuICBjcmVhdGVXZWJTb2NrZXRSZXBseVN0dWIsXG4gIHJlc29sdmVXZWJTb2NrZXRDbG9zZURlc2NyaXB0b3IsXG4gIHJlc29sdmVXZWJTb2NrZXRQbHVnaW5PcHRpb25zLFxufSBmcm9tIFwiLi93ZWJzb2NrZXQtaGVscGVyc1wiO1xuXG5pbnRlcmZhY2UgVXBsb2FkZWRSZXF1ZXN0RmlsZXMge1xuICBidWZmZXJlZEZpbGVzOiBCdWZmZXJlZEZpbGVbXTtcbiAgdXBsb2FkZWRGaWxlczogVXBsb2FkZWRGaWxlW107XG59XG5cbnR5cGUgQXBpQXJndW1lbnQgPVxuICB8IHN0cmluZ1xuICB8IG51bWJlclxuICB8IGJvb2xlYW5cbiAgfCBiaWdpbnRcbiAgfCBzeW1ib2xcbiAgfCBDYWxsYWJsZUZ1bmN0aW9uXG4gIHwgb2JqZWN0XG4gIHwgbnVsbFxuICB8IHVuZGVmaW5lZDtcbnR5cGUgQXBpTWV0aG9kUmVzdWx0ID0gQXBpQXJndW1lbnQgfCB2b2lkO1xuXG5mdW5jdGlvbiB0b0FwaUFyZ3VtZW50PFZhbHVlPih2YWx1ZTogVmFsdWUpOiBBcGlBcmd1bWVudCB7XG4gIGlmICh2YWx1ZSA9PT0gbnVsbCkgcmV0dXJuIG51bGw7XG4gIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkKSByZXR1cm4gdW5kZWZpbmVkO1xuICBpZiAodmFsdWUgPT09IHRydWUpIHJldHVybiB0cnVlO1xuICBpZiAodmFsdWUgPT09IGZhbHNlKSByZXR1cm4gZmFsc2U7XG4gIGlmIChpc1N0cmluZ1ZhbHVlKHZhbHVlKSkgcmV0dXJuIHZhbHVlO1xuICBpZiAoaXNOdW1iZXJWYWx1ZSh2YWx1ZSkpIHJldHVybiB2YWx1ZTtcbiAgaWYgKGlzQmlnSW50VmFsdWUodmFsdWUpKSByZXR1cm4gdmFsdWU7XG4gIGlmIChpc1N5bWJvbFZhbHVlKHZhbHVlKSkgcmV0dXJuIHZhbHVlO1xuICBpZiAoaXNGdW5jdGlvblZhbHVlKHZhbHVlKSkgcmV0dXJuIHZhbHVlO1xuICBpZiAoaXNPYmplY3RWYWx1ZSh2YWx1ZSkpIHtcbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cbiAgdGhyb3cgbmV3IEVycm9yKFwi7KeA7JuQ7ZWY7KeAIOyViuuKlCBBUEkg7J247IiYIO2DgOyeheyeheuLiOuLpC5cIik7XG59XG5cbmZ1bmN0aW9uIHRvQXBpQXJndW1lbnRNYXA8VmFsdWUgZXh0ZW5kcyBvYmplY3Q+KHZhbHVlOiBWYWx1ZSk6IE1hcDxzdHJpbmcsIEFwaUFyZ3VtZW50PiB7XG4gIHJldHVybiBuZXcgTWFwKE9iamVjdC5lbnRyaWVzKHZhbHVlKS5tYXAoKFtrZXksIGl0ZW1dKSA9PiBba2V5LCB0b0FwaUFyZ3VtZW50KGl0ZW0pXSkpO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVVbmF2YWlsYWJsZVNTRTxUIGV4dGVuZHMgWm9kT2JqZWN0PihfZXZlbnRzOiBUKTogbmV2ZXIge1xuICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgXCJjcmVhdGVTU0UgaXMgbm90IGF2YWlsYWJsZSBpbiB3ZWJzb2NrZXQgY29udGV4dC4gRGVmaW5lIHdlYnNvY2tldENvbnRleHRQcm92aWRlciBpZiB5b3VyIGNvbnRleHQgc2V0dXAgZGVwZW5kcyBvbiBTU0UgaGVscGVycy5cIixcbiAgKTtcbn1cblxuZnVuY3Rpb24gcHJpbnREaW1TdW1tYXJ5KG1lc3NhZ2U6IHN0cmluZyk6IHZvaWQge1xuICBjb25zb2xlLmxvZyhjaGFsay5kaW0oYOKckyAke21lc3NhZ2V9YCkpO1xufVxuXG5mdW5jdGlvbiBwcmludEdyZWVuU3VtbWFyeShtZXNzYWdlOiBzdHJpbmcpOiB2b2lkIHtcbiAgY29uc29sZS5sb2coY2hhbGsuZ3JlZW4oYOKckyAke21lc3NhZ2V9YCkpO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFNvbmFtdVRlc3RpbmdTbmFwc2hvdCB7XG4gIGFwaVJvb3RQYXRoOiBBYnNvbHV0ZVBhdGggfCBudWxsO1xuICBjb25maWc6IFNvbmFtdUNvbmZpZyB8IG51bGw7XG4gIHN5bmNlcjogU3luY2VyIHwgbnVsbDtcbiAgaHR0cFZhbGlkYXRvcnM6IFdlYWtNYXA8RXh0ZW5kZWRBcGksIEh0dHBWYWxpZGF0b3I+O1xuICBwZW5kaW5nSHR0cFZhbGlkYXRvcnM6IFdlYWtNYXA8RXh0ZW5kZWRBcGksIFByb21pc2U8SHR0cFZhbGlkYXRvcj4+O1xuICBhb3RIdHRwVmFsaWRhdG9yUmVnaXN0cnk6IEh0dHBWYWxpZGF0b3JSZWdpc3RyeSB8IHVuZGVmaW5lZDtcbiAgcHJlcGFyZWRBcGlzOiByZWFkb25seSBFeHRlbmRlZEFwaVtdO1xuICBwcmVwYXJlZE1vZGVsczogTG9hZGVkTW9kZWxzO1xuICB3ZWJzb2NrZXRSdW50aW1lOiBXZWJTb2NrZXRSdW50aW1lIHwgbnVsbDtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBTb25hbXVIdHRwVmFsaWRhdG9yRGVwZW5kZW5jaWVzIHtcbiAgY3JlYXRlVmFsaWRhdG9yOiB0eXBlb2YgY3JlYXRlSHR0cFZhbGlkYXRvcjtcbiAgYXNzZXJ0UmVnaXN0cnk6IHR5cGVvZiBhc3NlcnRIdHRwVmFsaWRhdG9yUmVnaXN0cnk7XG59XG5cbmV4cG9ydCBjb25zdCBkZWZhdWx0U29uYW11SHR0cFZhbGlkYXRvckRlcGVuZGVuY2llczogU29uYW11SHR0cFZhbGlkYXRvckRlcGVuZGVuY2llcyA9IHtcbiAgY3JlYXRlVmFsaWRhdG9yOiBjcmVhdGVIdHRwVmFsaWRhdG9yLFxuICBhc3NlcnRSZWdpc3RyeTogYXNzZXJ0SHR0cFZhbGlkYXRvclJlZ2lzdHJ5LFxufTtcblxuY2xhc3MgU29uYW11Q2xhc3Mge1xuICBwdWJsaWMgaXNJbml0aWFsaXplZDogYm9vbGVhbiA9IGZhbHNlO1xuICBwdWJsaWMgZm9yVGVzdGluZzogYm9vbGVhbiA9IGZhbHNlO1xuICBwdWJsaWMgYXN5bmNMb2NhbFN0b3JhZ2U6IEFzeW5jTG9jYWxTdG9yYWdlPHtcbiAgICBjb250ZXh0OiBSdW50aW1lQ29udGV4dDtcbiAgfT4gPSBuZXcgQXN5bmNMb2NhbFN0b3JhZ2UoKTtcbiAgcHJpdmF0ZSBodHRwVmFsaWRhdG9yczogV2Vha01hcDxFeHRlbmRlZEFwaSwgSHR0cFZhbGlkYXRvcj4gPSBuZXcgV2Vha01hcCgpO1xuICBwcml2YXRlIHBlbmRpbmdIdHRwVmFsaWRhdG9yczogV2Vha01hcDxFeHRlbmRlZEFwaSwgUHJvbWlzZTxIdHRwVmFsaWRhdG9yPj4gPSBuZXcgV2Vha01hcCgpO1xuICBwcml2YXRlIGFvdEh0dHBWYWxpZGF0b3JSZWdpc3RyeTogSHR0cFZhbGlkYXRvclJlZ2lzdHJ5IHwgdW5kZWZpbmVkO1xuICBwcml2YXRlIHByZXBhcmVkQXBpczogcmVhZG9ubHkgRXh0ZW5kZWRBcGlbXSA9IFtdO1xuICBwcml2YXRlIHByZXBhcmVkTW9kZWxzOiBMb2FkZWRNb2RlbHMgPSB7fTtcblxuICBwdWJsaWMgZ2V0Q29udGV4dDxUIGV4dGVuZHMgUnVudGltZUNvbnRleHQgPSBDb250ZXh0PigpOiBUIHtcbiAgICBjb25zdCBzdG9yZSA9IHRoaXMuYXN5bmNMb2NhbFN0b3JhZ2UuZ2V0U3RvcmUoKTtcbiAgICBpZiAoc3RvcmU/LmNvbnRleHQpIHtcbiAgICAgIHJldHVybiAvKiBTQUZFVFk6IEFQSSDrjbDsvZTroIjsnbTthLDsmYAgWm9kIOqygOymneq4sCDrk7HroZ0g6rOE7JW97J20IOydtCDqsJLsnZgg7YOA7J6F7J2EIOuztOyepe2VnOuLpC4gKi8gc3RvcmUuY29udGV4dCBhcyBUO1xuICAgIH1cblxuICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViA9PT0gXCJ0ZXN0XCIpIHtcbiAgICAgIC8vIO2FjOyKpO2MhSDtmZjqsr3sl5DshJwg7Luo7YWN7Iqk7Yq46rCAIOyjvOyeheuQmOyngCDslYrsnYAg6rK97JqwIOu5iCDsu6jthY3siqTtirgg66as7YS0XG4gICAgICBjb25zdCBtb2NrQ29udGV4dCA9IHtcbiAgICAgICAgdHJhbnNwb3J0OiBcImh0dHBcIixcbiAgICAgICAgcmVxdWVzdDogbnVsbCxcbiAgICAgICAgcmVwbHk6IG51bGwsXG4gICAgICAgIGhlYWRlcnM6IHt9LFxuICAgICAgICBjcmVhdGVTU0U6IChzY2hlbWE6IFpvZE9iamVjdCkgPT4gY3JlYXRlTW9ja1NTRUZhY3Rvcnkoc2NoZW1hKSxcbiAgICAgICAgbG9jYWxlOiBcIlwiLFxuICAgICAgICB1c2VyOiBudWxsLFxuICAgICAgICBzZXNzaW9uOiBudWxsLFxuICAgICAgICBuYWl0ZVN0b3JlOiBuZXcgTWFwPHN0cmluZywgYW55PigpLFxuICAgICAgfTtcbiAgICAgIC8vIFNBRkVUWTog7YWM7Iqk7Yq4IOq4sOuzuCDsu6jthY3siqTtirjripQgSFRUUCBDb250ZXh07J2066mwIOq4sOuzuCDsoJzrhKTrpq3qs7wg7J287LmY7ZWc64ukLlxuICAgICAgcmV0dXJuIC8qIFNBRkVUWTog7YWM7Iqk7Yq4IOq4sOuzuCDsu6jthY3siqTtirjripQg7JqU7LKtIOuylOychOqwgCDsl4bripQgSFRUUCDsu6jthY3siqTtirgg64yA7LK06rCS7J6F64uI64ukLiAqLyBtb2NrQ29udGV4dCBhcyBUICZcbiAgICAgICAgdHlwZW9mIG1vY2tDb250ZXh0O1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJTb25hbXUgY2Fubm90IGZpbmQgY29udGV4dFwiKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFwaVJvb3RQYXRoVmFsdWU6IEFic29sdXRlUGF0aCB8IG51bGwgPSBudWxsO1xuICBzZXQgYXBpUm9vdFBhdGgoYXBpUm9vdFBhdGg6IEFic29sdXRlUGF0aCkge1xuICAgIHRoaXMuYXBpUm9vdFBhdGhWYWx1ZSA9IGFwaVJvb3RQYXRoO1xuICB9XG4gIGdldCBhcGlSb290UGF0aCgpOiBBYnNvbHV0ZVBhdGgge1xuICAgIGlmICh0aGlzLmFwaVJvb3RQYXRoVmFsdWUgPT09IG51bGwpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlNvbmFtdSBoYXMgbm90IGJlZW4gaW5pdGlhbGl6ZWRcIik7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmFwaVJvb3RQYXRoVmFsdWU7XG4gIH1cbiAgZ2V0IGFwcFJvb3RQYXRoKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuYXBpUm9vdFBhdGguc3BsaXQocGF0aC5zZXApLnNsaWNlKDAsIC0xKS5qb2luKHBhdGguc2VwKTtcbiAgfVxuXG4gIHByaXZhdGUgZGJDb25maWdWYWx1ZTogU29uYW11REJDb25maWcgfCBudWxsID0gbnVsbDtcbiAgc2V0IGRiQ29uZmlnKGRiQ29uZmlnOiBTb25hbXVEQkNvbmZpZykge1xuICAgIHRoaXMuZGJDb25maWdWYWx1ZSA9IGRiQ29uZmlnO1xuICB9XG4gIGdldCBkYkNvbmZpZygpOiBTb25hbXVEQkNvbmZpZyB7XG4gICAgaWYgKHRoaXMuZGJDb25maWdWYWx1ZSA9PT0gbnVsbCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiU29uYW11IGhhcyBub3QgYmVlbiBpbml0aWFsaXplZFwiKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuZGJDb25maWdWYWx1ZTtcbiAgfVxuXG4gIHByaXZhdGUgc3luY2VyVmFsdWU6IFN5bmNlciB8IG51bGwgPSBudWxsO1xuICBzZXQgc3luY2VyKHN5bmNlcjogU3luY2VyKSB7XG4gICAgdGhpcy5zeW5jZXJWYWx1ZSA9IHN5bmNlcjtcbiAgfVxuICBnZXQgc3luY2VyKCk6IFN5bmNlciB7XG4gICAgaWYgKHRoaXMuc3luY2VyVmFsdWUgPT09IG51bGwpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlNvbmFtdSBoYXMgbm90IGJlZW4gaW5pdGlhbGl6ZWRcIik7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnN5bmNlclZhbHVlO1xuICB9XG5cbiAgcHJpdmF0ZSBjb25maWdWYWx1ZTogU29uYW11Q29uZmlnIHwgbnVsbCA9IG51bGw7XG4gIHNldCBjb25maWcoY29uZmlnOiBTb25hbXVDb25maWcpIHtcbiAgICB0aGlzLmNvbmZpZ1ZhbHVlID0gY29uZmlnO1xuICB9XG4gIGdldCBjb25maWcoKTogU29uYW11Q29uZmlnIHtcbiAgICBpZiAodGhpcy5jb25maWdWYWx1ZSA9PT0gbnVsbCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiU29uYW11IGhhcyBub3QgYmVlbiBpbml0aWFsaXplZFwiKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuY29uZmlnVmFsdWU7XG4gIH1cblxuICBwdWJsaWMgcmVhZG9ubHkgc2VjcmV0czogU29uYW11U2VjcmV0cyA9IGdldFNlY3JldHMoKTtcblxuICBwcml2YXRlIHN0b3JhZ2VWYWx1ZTogU3RvcmFnZU1hbmFnZXIgfCBudWxsID0gbnVsbDtcbiAgLyoqXG4gICAqIFN0b3JhZ2VNYW5hZ2VyIOyduOyKpO2EtOyKpFxuICAgKi9cbiAgZ2V0IHN0b3JhZ2UoKTogU3RvcmFnZU1hbmFnZXIge1xuICAgIGlmICghdGhpcy5zdG9yYWdlVmFsdWUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlN0b3JhZ2UgaGFzIG5vdCBiZWVuIGluaXRpYWxpemVkLiBDaGVjayBzdG9yYWdlIGNvbmZpZy5cIik7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnN0b3JhZ2VWYWx1ZTtcbiAgfVxuXG4gIHByaXZhdGUgY2FjaGVWYWx1ZTogQ2FjaGVNYW5hZ2VyIHwgbnVsbCA9IG51bGw7XG4gIC8qKlxuICAgKiBDYWNoZU1hbmFnZXIg7J247Iqk7YS07IqkIChCZW50b0NhY2hlKVxuICAgKi9cbiAgZ2V0IGNhY2hlKCk6IENhY2hlTWFuYWdlciB7XG4gICAgaWYgKCF0aGlzLmNhY2hlVmFsdWUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkNhY2hlIGhhcyBub3QgYmVlbiBpbml0aWFsaXplZC4gQ2hlY2sgY2FjaGUgY29uZmlnIGluIHNvbmFtdS5jb25maWcudHMuXCIpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5jYWNoZVZhbHVlO1xuICB9XG5cbiAgcHJpdmF0ZSB3b3JrZmxvd3NWYWx1ZTogV29ya2Zsb3dNYW5hZ2VyIHwgbnVsbCA9IG51bGw7XG4gIGdldCB3b3JrZmxvd3MoKTogV29ya2Zsb3dNYW5hZ2VyIHtcbiAgICBpZiAodGhpcy53b3JrZmxvd3NWYWx1ZSA9PT0gbnVsbCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiU29uYW11IGhhcyBub3QgYmVlbiBpbml0aWFsaXplZFwiKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy53b3JrZmxvd3NWYWx1ZTtcbiAgfVxuXG4gIHByaXZhdGUgYXV0aFZhbHVlOiBBdXRoPEJldHRlckF1dGhPcHRpb25zPiB8IG51bGwgPSBudWxsO1xuICBnZXQgYXV0aCgpOiBBdXRoPEJldHRlckF1dGhPcHRpb25zPiB7XG4gICAgaWYgKCF0aGlzLmF1dGhWYWx1ZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQXV0aCBoYXMgbm90IGJlZW4gaW5pdGlhbGl6ZWQuIENoZWNrIGF1dGggY29uZmlnIGluIHNvbmFtdS5jb25maWcudHMuXCIpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5hdXRoVmFsdWU7XG4gIH1cblxuICBwcml2YXRlIGRldlZpdGVzdE1hbmFnZXJWYWx1ZTogRGV2Vml0ZXN0TWFuYWdlciB8IG51bGwgPSBudWxsO1xuICBnZXQgZGV2Vml0ZXN0TWFuYWdlcigpOiBEZXZWaXRlc3RNYW5hZ2VyIHwgbnVsbCB7XG4gICAgcmV0dXJuIHRoaXMuZGV2Vml0ZXN0TWFuYWdlclZhbHVlO1xuICB9XG4gIHNldCBkZXZWaXRlc3RNYW5hZ2VyKG1hbmFnZXI6IERldlZpdGVzdE1hbmFnZXIgfCBudWxsKSB7XG4gICAgdGhpcy5kZXZWaXRlc3RNYW5hZ2VyVmFsdWUgPSBtYW5hZ2VyO1xuICB9XG5cbiAgLy8gU29uYW116rCAIHJ1bnRpbWXsnYQg7KeB7KCRIOyGjOycoO2VtCByZWdpc3RyeS9jb25uZWN0aW9uIGxpZmVjeWNsZeydhCDslaDtlIzrpqzsvIDsnbTshZgg7IiY66qF7KO86riw7JmAIOuPmeq4sO2ZlO2VqFxuICBwcml2YXRlIHdlYnNvY2tldFJ1bnRpbWVWYWx1ZTogV2ViU29ja2V0UnVudGltZSB8IG51bGwgPSBudWxsO1xuICAvLyDqsJnsnYAgRmFzdGlmeSDsnbjsiqTthLTsiqTsl5AgQGZhc3RpZnkvd2Vic29ja2V07J2EIOykkeuztSDrk7HroZ3tlZjripQg6rKD7J2EIFdlYWtTZXTsnLzroZwg7LCo64uo7ZWoXG4gIHByaXZhdGUgcmVhZG9ubHkgd2Vic29ja2V0UGx1Z2luU2VydmVycyA9IG5ldyBXZWFrU2V0PFxuICAgIEZhc3RpZnlJbnN0YW5jZTxTZXJ2ZXIsIEluY29taW5nTWVzc2FnZSwgU2VydmVyUmVzcG9uc2U+XG4gID4oKTtcbiAgZ2V0IHdlYnNvY2tldFJ1bnRpbWUoKTogV2ViU29ja2V0UnVudGltZSB7XG4gICAgaWYgKCF0aGlzLndlYnNvY2tldFJ1bnRpbWVWYWx1ZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiV2ViU29ja2V0IHJ1bnRpbWUgaGFzIG5vdCBiZWVuIGluaXRpYWxpemVkLlwiKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMud2Vic29ja2V0UnVudGltZVZhbHVlO1xuICB9XG4gIHNldCB3ZWJzb2NrZXRSdW50aW1lKHJ1bnRpbWU6IFdlYlNvY2tldFJ1bnRpbWUgfCBudWxsKSB7XG4gICAgdGhpcy53ZWJzb2NrZXRSdW50aW1lVmFsdWUgPSBydW50aW1lO1xuICB9XG5cbiAgY2FwdHVyZVRlc3RpbmdTbmFwc2hvdCgpOiBTb25hbXVUZXN0aW5nU25hcHNob3Qge1xuICAgIHJldHVybiB7XG4gICAgICBhcGlSb290UGF0aDogdGhpcy5hcGlSb290UGF0aFZhbHVlLFxuICAgICAgY29uZmlnOiB0aGlzLmNvbmZpZ1ZhbHVlLFxuICAgICAgc3luY2VyOiB0aGlzLnN5bmNlclZhbHVlLFxuICAgICAgaHR0cFZhbGlkYXRvcnM6IHRoaXMuaHR0cFZhbGlkYXRvcnMsXG4gICAgICBwZW5kaW5nSHR0cFZhbGlkYXRvcnM6IHRoaXMucGVuZGluZ0h0dHBWYWxpZGF0b3JzLFxuICAgICAgYW90SHR0cFZhbGlkYXRvclJlZ2lzdHJ5OiB0aGlzLmFvdEh0dHBWYWxpZGF0b3JSZWdpc3RyeSxcbiAgICAgIHByZXBhcmVkQXBpczogdGhpcy5wcmVwYXJlZEFwaXMsXG4gICAgICBwcmVwYXJlZE1vZGVsczogdGhpcy5wcmVwYXJlZE1vZGVscyxcbiAgICAgIHdlYnNvY2tldFJ1bnRpbWU6IHRoaXMud2Vic29ja2V0UnVudGltZVZhbHVlLFxuICAgIH07XG4gIH1cblxuICByZXN0b3JlVGVzdGluZ1NuYXBzaG90KHNuYXBzaG90OiBTb25hbXVUZXN0aW5nU25hcHNob3QpOiB2b2lkIHtcbiAgICB0aGlzLmFwaVJvb3RQYXRoVmFsdWUgPSBzbmFwc2hvdC5hcGlSb290UGF0aDtcbiAgICB0aGlzLmNvbmZpZ1ZhbHVlID0gc25hcHNob3QuY29uZmlnO1xuICAgIHRoaXMuc3luY2VyVmFsdWUgPSBzbmFwc2hvdC5zeW5jZXI7XG4gICAgdGhpcy5odHRwVmFsaWRhdG9ycyA9IHNuYXBzaG90Lmh0dHBWYWxpZGF0b3JzO1xuICAgIHRoaXMucGVuZGluZ0h0dHBWYWxpZGF0b3JzID0gc25hcHNob3QucGVuZGluZ0h0dHBWYWxpZGF0b3JzO1xuICAgIHRoaXMuYW90SHR0cFZhbGlkYXRvclJlZ2lzdHJ5ID0gc25hcHNob3QuYW90SHR0cFZhbGlkYXRvclJlZ2lzdHJ5O1xuICAgIHRoaXMucHJlcGFyZWRBcGlzID0gc25hcHNob3QucHJlcGFyZWRBcGlzO1xuICAgIHRoaXMucHJlcGFyZWRNb2RlbHMgPSBzbmFwc2hvdC5wcmVwYXJlZE1vZGVscztcbiAgICB0aGlzLndlYnNvY2tldFJ1bnRpbWVWYWx1ZSA9IHNuYXBzaG90LndlYnNvY2tldFJ1bnRpbWU7XG4gIH1cblxuICAvLyBITVIg7LKY66asOiDtjIzsnbwg7Iuc7Iqk7YWcIOqwkOyLnCArIEhNUi9zeW5jIOyCrOydtO2BtCDsi6TtlonsnYAgd2F0Y2hlciDrqqjrk4jroZwg7JyE7J6E7ZWp64uI64ukLlxuICBwdWJsaWMgd2F0Y2hlcjogRlNXYXRjaGVyIHwgbnVsbCA9IG51bGw7XG5cbiAgcHVibGljIHNlcnZlcjogRmFzdGlmeUluc3RhbmNlIHwgbnVsbCA9IG51bGw7XG5cbiAgYXN5bmMgaW5pdEZvclRlc3RpbmcoKSB7XG4gICAgYXdhaXQgdGhpcy5pbml0KHRydWUsIGZhbHNlLCB1bmRlZmluZWQsIHRydWUpO1xuICB9XG5cbiAgYXN5bmMgaW5pdChcbiAgICBkb1NpbGVudDogYm9vbGVhbiA9IGZhbHNlLFxuICAgIGVuYWJsZVN5bmM6IGJvb2xlYW4gPSB0cnVlLFxuICAgIGFwaVJvb3RQYXRoPzogQWJzb2x1dGVQYXRoLFxuICAgIGZvclRlc3Rpbmc6IGJvb2xlYW4gPSBmYWxzZSxcbiAgKSB7XG4gICAgdGhpcy5mb3JUZXN0aW5nID0gZm9yVGVzdGluZztcblxuICAgIGlmICh0aGlzLmlzSW5pdGlhbGl6ZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBpbml0U3RhcnQgPSBwZXJmb3JtYW5jZS5ub3coKTtcblxuICAgIC8vIEFQSSDro6jtirgg7Yyo7IqkXG4gICAgY29uc3QgeyBmaW5kQXBpUm9vdFBhdGggfSA9IGF3YWl0IGltcG9ydChcIi4uL3V0aWxzL3V0aWxzXCIpO1xuICAgIHRoaXMuYXBpUm9vdFBhdGggPSBhcGlSb290UGF0aCA/PyBmaW5kQXBpUm9vdFBhdGgoKTtcbiAgICBjb25zdCBiYXNlRW52QmVmb3JlQ29uZmlnTG9hZCA9IHsgLi4ucHJvY2Vzcy5lbnYgfTtcblxuICAgIC8vIOyEpOygleydhCDroZzrlKntlZjripQg6rKD67aA7YSwIOyLnOyekVxuICAgIGNvbnN0IGNvbmZpZ1N0YXJ0ID0gcGVyZm9ybWFuY2Uubm93KCk7XG4gICAgY29uc3QgeyBsb2FkQ29uZmlnIH0gPSBhd2FpdCBpbXBvcnQoXCIuL2NvbmZpZ1wiKTtcbiAgICB0aGlzLmNvbmZpZyA9IGF3YWl0IGxvYWRDb25maWcodGhpcy5hcGlSb290UGF0aCk7XG4gICAgY29uc3QgY29uZmlnVGltZSA9IHBlcmZvcm1hbmNlLm5vdygpIC0gY29uZmlnU3RhcnQ7XG4gICAgc2V0U0RDb25maWcodGhpcy5jb25maWcuaTE4bik7XG4gICAgLy8gc29uYW11LmNvbmZpZy50cyDquLDrs7jqsJIg7ISk7KCVXG4gICAgdGhpcy5jb25maWcuZGF0YWJhc2UuZGF0YWJhc2UgPSB0aGlzLmNvbmZpZy5kYXRhYmFzZS5kYXRhYmFzZSA/PyBcInBnXCI7XG4gICAgdGhpcy5jb25maWcuZGF0YWJhc2UuZGVmYXVsdE9wdGlvbnMgPSB0aGlzLmNvbmZpZy5kYXRhYmFzZS5kZWZhdWx0T3B0aW9ucyA/PyB7fTtcbiAgICB0aGlzLmNvbmZpZy5kYXRhYmFzZS5kZWZhdWx0T3B0aW9ucy5jbGllbnQgPSB0aGlzLmNvbmZpZy5kYXRhYmFzZS5kYXRhYmFzZSA/PyBcInBnXCI7XG5cbiAgICAvLyDroZzquYUg7ISk7KCVXG4gICAgY29uc3QgeyBjb25maWd1cmVMb2dUYXBlIH0gPSBhd2FpdCBpbXBvcnQoXCIuLi9sb2dnZXIvY29uZmlndXJlXCIpO1xuICAgIGlmICh0aGlzLmNvbmZpZy5sb2dnaW5nICE9PSBmYWxzZSkge1xuICAgICAgYXdhaXQgY29uZmlndXJlTG9nVGFwZSh7XG4gICAgICAgIC4uLnRoaXMuY29uZmlnLmxvZ2dpbmcsXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvLyBEQiDroZzrk5xcbiAgICBjb25zdCB7IERCOiBSdW50aW1lREIgfSA9IGF3YWl0IGltcG9ydChcIi4uL2RhdGFiYXNlL2RiXCIpO1xuICAgIGNvbnN0IHsgaXNMb2NhbDogaXNMb2NhbEVudmlyb25tZW50IH0gPSBhd2FpdCBpbXBvcnQoXCIuLi91dGlscy9jb250cm9sbGVyXCIpO1xuICAgIGNvbnN0IGVudmlyb25tZW50U25hcHNob3RzID0gaXNMb2NhbEVudmlyb25tZW50KClcbiAgICAgID8gcmVhZEFsbEVudmlyb25tZW50U25hcHNob3RzKHRoaXMuYXBpUm9vdFBhdGgsIGJhc2VFbnZCZWZvcmVDb25maWdMb2FkKVxuICAgICAgOiB1bmRlZmluZWQ7XG4gICAgdGhpcy5kYkNvbmZpZyA9IFJ1bnRpbWVEQi5nZW5lcmF0ZURCQ29uZmlnKFxuICAgICAgdGhpcy5jb25maWcuZGF0YWJhc2UsXG4gICAgICB0aGlzLmNvbmZpZy5wcm9qZWN0TmFtZSxcbiAgICAgIGVudmlyb25tZW50U25hcHNob3RzLFxuICAgICk7XG4gICAgUnVudGltZURCLnNldENvbmZpZyh0aGlzLmRiQ29uZmlnKTtcblxuICAgIC8vIEVudGl0eSDroZzrk5xcbiAgICAvLyDthYzsiqTtirjsl5DshJzrj4QgRW50aXR5IOygleuztOuKlCDtlYTsmpTtlanri4jri6QuXG4gICAgLy8gdXBzZXJ06rCAIOygnOuMgOuhnCDsnpHrj5ntlZjroKTrqbQgZW50aXR57J2YIHVuaXF1ZSBpbmRleCDsoJXrs7TqsIAg7ZWE7JqU7ZWY6riwIOuVjOusuOyeheuLiOuLpC5cbiAgICBjb25zdCB7IEVudGl0eU1hbmFnZXIgfSA9IGF3YWl0IGltcG9ydChcIi4uL2VudGl0eS9lbnRpdHktbWFuYWdlclwiKTtcbiAgICBhd2FpdCBFbnRpdHlNYW5hZ2VyLmF1dG9sb2FkKGRvU2lsZW50KTtcblxuICAgIC8vIENhY2hlIOy0iOq4sO2ZlFxuICAgIGF3YWl0IHRoaXMuaW5pdGlhbGl6ZUNhY2hlKHRoaXMuY29uZmlnLnNlcnZlci5jYWNoZSwgZm9yVGVzdGluZyk7XG5cbiAgICAvLyBCZXR0ZXJBdXRoIOy0iOq4sO2ZlFxuICAgIGNvbnN0IGF1dGhDb25maWcgPSB0aGlzLmNvbmZpZy5zZXJ2ZXIuYXV0aDtcbiAgICBpZiAoYXV0aENvbmZpZykge1xuICAgICAgLy8g7IKs7Jqp7J6QIOyEpOygleqzvCDquLDrs7jqsJLsnYQgbWVyZ2VcbiAgICAgIGNvbnN0IG1lcmdlZEZpZWxkTWFwcGluZ3MgPSBtZXJnZShCQVNFX0ZJRUxEX01BUFBJTkdTLCBhdXRoQ29uZmlnKTtcblxuICAgICAgLy8gYmV0dGVyLWF1dGgg7J247Iqk7YS07IqkIOyDneyEsVxuICAgICAgY29uc3QgeyBiZXR0ZXJBdXRoIH0gPSBhd2FpdCBpbXBvcnQoXCJiZXR0ZXItYXV0aFwiKTtcbiAgICAgIGNvbnN0IHsgc29uYW11S25leEFkYXB0ZXIgfSA9IGF3YWl0IGltcG9ydChcIi4uL2F1dGgva25leC1hZGFwdGVyXCIpO1xuXG4gICAgICBjb25zdCBhdXRoT3B0aW9uczogQmV0dGVyQXV0aE9wdGlvbnMgPSB7XG4gICAgICAgIGRhdGFiYXNlOiBzb25hbXVLbmV4QWRhcHRlcigpLFxuICAgICAgICAuLi5tZXJnZWRGaWVsZE1hcHBpbmdzLFxuICAgICAgfTtcbiAgICAgIHRoaXMuYXV0aFZhbHVlID0gYmV0dGVyQXV0aChhdXRoT3B0aW9ucyk7XG4gICAgfVxuXG4gICAgLy8g7YWM7Iqk7YyF7J24IOqyveyasCDsi7Htgawg7JeG7J20IOykkeuLqFxuICAgIGlmIChmb3JUZXN0aW5nKSB7XG4gICAgICB0aGlzLmlzSW5pdGlhbGl6ZWQgPSB0cnVlO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIFRhc2sg65Ox66GdXG4gICAgYXdhaXQgdGhpcy5pbml0aWFsaXplV29ya2Zsb3dzKHRoaXMuY29uZmlnLnRhc2tzKTtcblxuICAgIC8vIFN5bmNlclxuICAgIGNvbnN0IHsgU3luY2VyIH0gPSBhd2FpdCBpbXBvcnQoXCIuLi9zeW5jZXIvc3luY2VyXCIpO1xuICAgIHRoaXMuc3luY2VyID0gbmV3IFN5bmNlcigpO1xuXG4gICAgLy8gQXV0b2xvYWQ6IE1vZGVscyAvIFR5cGVzIC8gQVBJcyAvIFdvcmtmbG93cyAvIFRlbXBsYXRlcyAvIFNTUiBSb3V0ZXNcbiAgICBhd2FpdCB0aGlzLnN5bmNlci5hdXRvbG9hZFR5cGVzKCk7XG4gICAgYXdhaXQgdGhpcy5zeW5jZXIuYXV0b2xvYWRNb2RlbHMoKTtcbiAgICBhd2FpdCB0aGlzLnN5bmNlci5hdXRvbG9hZEFwaXMoKTtcbiAgICBhd2FpdCB0aGlzLnN5bmNlci5hdXRvbG9hZFdvcmtmbG93cygpO1xuICAgIGNvbnN0IHsgVGVtcGxhdGVNYW5hZ2VyIH0gPSBhd2FpdCBpbXBvcnQoXCIuLi90ZW1wbGF0ZVwiKTtcbiAgICBhd2FpdCBUZW1wbGF0ZU1hbmFnZXIuYXV0b2xvYWQoKTtcbiAgICBhd2FpdCB0aGlzLnN5bmNlci5hdXRvbG9hZFNzclJvdXRlcygpO1xuXG4gICAgY29uc3QgeyBpc0xvY2FsLCBpc1Rlc3QsIGlzSG90UmVsb2FkU2VydmVyIH0gPSBhd2FpdCBpbXBvcnQoXCIuLi91dGlscy9jb250cm9sbGVyXCIpO1xuICAgIGlmIChpc0xvY2FsKCkgJiYgIWlzVGVzdCgpICYmIGlzSG90UmVsb2FkU2VydmVyKCkgJiYgZW5hYmxlU3luYykge1xuICAgICAgYXdhaXQgdGhpcy5zeW5jZXIuc3luYygpO1xuICAgICAgYXdhaXQgdGhpcy5zdGFydFdhdGNoZXIoKTtcbiAgICB9XG5cbiAgICB0aGlzLmlzSW5pdGlhbGl6ZWQgPSB0cnVlO1xuICAgIHRoaXMuaW5pdEVsYXBzZWQgPSBwZXJmb3JtYW5jZS5ub3coKSAtIGluaXRTdGFydDtcbiAgICB0aGlzLmNvbmZpZ0VsYXBzZWQgPSBjb25maWdUaW1lO1xuICB9XG5cbiAgcHJpdmF0ZSBpbml0RWxhcHNlZCA9IDA7XG4gIHByaXZhdGUgY29uZmlnRWxhcHNlZCA9IDA7XG5cbiAgYXN5bmMgY3JlYXRlU2VydmVyKGluaXRPcHRpb25zPzogeyBlbmFibGVTeW5jPzogYm9vbGVhbjsgZG9TaWxlbnQ/OiBib29sZWFuIH0pIHtcbiAgICBpZiAoIXRoaXMuaXNJbml0aWFsaXplZCkge1xuICAgICAgYXdhaXQgdGhpcy5pbml0KGluaXRPcHRpb25zPy5kb1NpbGVudCwgaW5pdE9wdGlvbnM/LmVuYWJsZVN5bmMpO1xuICAgIH1cblxuICAgIGNvbnN0IG9wdGlvbnMgPSB0aGlzLmNvbmZpZy5zZXJ2ZXI7XG4gICAgY29uc3QgeyBkZWZhdWx0OiBmYXN0aWZ5IH0gPSBhd2FpdCBpbXBvcnQoXCJmYXN0aWZ5XCIpO1xuICAgIGNvbnN0IHsgZ2V0TG9nVGFwZUZhc3RpZnlMb2dnZXIgfSA9IGF3YWl0IGltcG9ydChcIkBsb2d0YXBlL2Zhc3RpZnlcIik7XG4gICAgY29uc3Qgc2VydmVyID0gZmFzdGlmeSh7XG4gICAgICAuLi5vcHRpb25zLmZhc3RpZnksXG4gICAgICBsb2dnZXI6XG4gICAgICAgIHRoaXMuY29uZmlnLmxvZ2dpbmcgIT09IGZhbHNlXG4gICAgICAgICAgPyBnZXRMb2dUYXBlRmFzdGlmeUxvZ2dlcih7XG4gICAgICAgICAgICAgIGNhdGVnb3J5OiB0aGlzLmNvbmZpZy5sb2dnaW5nPy5mYXN0aWZ5Q2F0ZWdvcnkgPz8gW1wiZmFzdGlmeVwiXSxcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgOiB1bmRlZmluZWQsXG4gICAgfSk7XG4gICAgdGhpcy5zZXJ2ZXIgPSBzZXJ2ZXI7XG4gICAgdGhpcy53ZWJzb2NrZXRSdW50aW1lID0gbmV3IFdlYlNvY2tldFJ1bnRpbWUob3B0aW9ucy53ZWJzb2NrZXQpO1xuXG4gICAgLy8gU3RvcmFnZSDshKTsoJUg4oaSIFN0b3JhZ2VNYW5hZ2VyIOyDneyEsVxuICAgIGlmIChvcHRpb25zLnN0b3JhZ2UpIHtcbiAgICAgIGNvbnN0IHsgU3RvcmFnZU1hbmFnZXIgfSA9IGF3YWl0IGltcG9ydChcIi4uL3N0b3JhZ2Uvc3RvcmFnZS1tYW5hZ2VyXCIpO1xuICAgICAgdGhpcy5zdG9yYWdlVmFsdWUgPSBuZXcgU3RvcmFnZU1hbmFnZXIob3B0aW9ucy5zdG9yYWdlKTtcbiAgICB9XG5cbiAgICAvLyDtlIzrn6zqt7jsnbgg65Ox66GdXG4gICAgaWYgKG9wdGlvbnMucGx1Z2lucykge1xuICAgICAgYXdhaXQgdGhpcy5yZWdpc3RlclBsdWdpbnMoc2VydmVyLCBvcHRpb25zLnBsdWdpbnMpO1xuICAgIH1cblxuICAgIGlmIChvcHRpb25zLmF1dGgpIHtcbiAgICAgIGF3YWl0IHRoaXMucmVnaXN0ZXJCZXR0ZXJBdXRoKHNlcnZlciwgb3B0aW9ucy5hdXRoKTtcbiAgICB9XG5cbiAgICAvLyBBUEkg65287Jqw7YyFIOyEpOyglVxuICAgIGF3YWl0IHRoaXMud2l0aEZhc3RpZnkoc2VydmVyLCBvcHRpb25zLmFwaUNvbmZpZywge1xuICAgICAgZW5hYmxlU3luYzogaW5pdE9wdGlvbnM/LmVuYWJsZVN5bmMsXG4gICAgICBkb1NpbGVudDogaW5pdE9wdGlvbnM/LmRvU2lsZW50LFxuICAgIH0pO1xuXG4gICAgLy8g7ISc67KEIOyLnOyekVxuICAgIGF3YWl0IHRoaXMuYm9vdChzZXJ2ZXIsIG9wdGlvbnMpO1xuXG4gICAgaWYgKCFpbml0T3B0aW9ucz8uZG9TaWxlbnQpIHtcbiAgICAgIHRoaXMucHJpbnRTdGFydHVwU3VtbWFyeSgpO1xuICAgIH1cblxuICAgIHJldHVybiBzZXJ2ZXI7XG4gIH1cblxuICBhc3luYyB3aXRoRmFzdGlmeShcbiAgICBzZXJ2ZXI6IEZhc3RpZnlJbnN0YW5jZTxTZXJ2ZXIsIEluY29taW5nTWVzc2FnZSwgU2VydmVyUmVzcG9uc2U+LFxuICAgIGNvbmZpZzogU29uYW11RmFzdGlmeUNvbmZpZyxcbiAgICBvcHRpb25zPzoge1xuICAgICAgZW5hYmxlU3luYz86IGJvb2xlYW47XG4gICAgICBkb1NpbGVudD86IGJvb2xlYW47XG4gICAgfSxcbiAgKSB7XG4gICAgaWYgKCF0aGlzLmlzSW5pdGlhbGl6ZWQpIHtcbiAgICAgIGF3YWl0IHRoaXMuaW5pdChvcHRpb25zPy5kb1NpbGVudCwgb3B0aW9ucz8uZW5hYmxlU3luYyk7XG4gICAgfVxuXG4gICAgdGhpcy5zZXJ2ZXIgPSBzZXJ2ZXI7XG4gICAgdGhpcy53ZWJzb2NrZXRSdW50aW1lID8/PSBuZXcgV2ViU29ja2V0UnVudGltZSh0aGlzLmNvbmZpZy5zZXJ2ZXIud2Vic29ja2V0KTtcbiAgICBhd2FpdCB0aGlzLnJlZnJlc2hIdHRwVmFsaWRhdG9ycygpO1xuXG4gICAgLy8gdGltZXpvbmUg7ISk7KCVXG4gICAgY29uc3QgdGltZXpvbmUgPSB0aGlzLmNvbmZpZy5hcGkudGltZXpvbmU7XG4gICAgaWYgKHRpbWV6b25lKSB7XG4gICAgICAvLyDtg4DsnoTsobTsl5Ag66ee6rKMIOydkeuLtSDrgqDsp5wg7Iqk7Yq466eB7J2EIOuzgO2ZmO2VtOyjvOyWtOyVvCDtlanri4jri6QuXG4gICAgICAvLyDqsIDroLkgdGltZXpvbmXsnbQgXCJBc2lhL1Nlb3VsXCIg7J2066m0XG4gICAgICAvLyBcIjIwMjUtMTEtMjFUMDA6MDA6MDAuMDAwWlwiIOulvCBcIjIwMjUtMTEtMjFUMDk6MDA6MDArMDk6MDBcIiDsnLzroZwg67OA7ZmY7ZW07KO87Ja07JW8IO2VqeuLiOuLpC5cbiAgICAgIGNvbnN0IHsgZm9ybWF0SW5UaW1lWm9uZSB9ID0gYXdhaXQgaW1wb3J0KFwiZGF0ZS1mbnMtdHpcIik7XG5cbiAgICAgIC8vIElTTyA4NjAxIOuCoOynnCDtmJXsi50g7KCV6rec7IudICjsmIg6IDIwMjQtMDEtMTVUMDk6MzA6MDAuMDAwWilcbiAgICAgIGNvbnN0IElTT19EQVRFX1JFR0VYID0gL15cXGR7NH0tXFxkezJ9LVxcZHsyfVRcXGR7Mn06XFxkezJ9OlxcZHsyfShcXC5cXGR7M30pP1okLztcblxuICAgICAgLy8gVOulvCDrkZjrn6zsi7wg7J6R7J2A65Sw7Ji07ZGc6rCAIOyXhuuLpOuptCBcIjIwMjUtMTEtMTkxNzYzNTQ2MTg5MDAwMTg6NTY6MjkrMDk6MDBcIuyZgCDqsJnsnYAg6rKw6rO86rCAIOuCmOyYteuLiOuLpC5cbiAgICAgIC8vIOydtOuKlCBkYXRlLWZucyDtirnsnoXri4jri6QuXG4gICAgICAvLyDsnbTroIfqsowg7ZW064+EIOq0nOywruyKteuLiOuLpC4gXCIyMDI1LTExLTE5VDE4OjU2OjI5KzA5OjAwXCIg66qo7JaR7Jy866GcIOyemCDrgpjsmLXri4jri6QuXG4gICAgICBjb25zdCBEQVRFX0ZPUk1BVCA9IFwieXl5eS1NTS1kZCdUJ0hIOm1tOnNzWFhYXCI7XG5cbiAgICAgIHNlcnZlci5zZXRSZXBseVNlcmlhbGl6ZXIoKHBheWxvYWQpID0+IHtcbiAgICAgICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHBheWxvYWQsIChfa2V5LCB2YWx1ZSkgPT4ge1xuICAgICAgICAgIGlmIChpc1N0cmluZ1ZhbHVlKHZhbHVlKSAmJiBJU09fREFURV9SRUdFWC50ZXN0KHZhbHVlKSkge1xuICAgICAgICAgICAgcmV0dXJuIGZvcm1hdEluVGltZVpvbmUoXG4gICAgICAgICAgICAgIG5ldyBEYXRlKHZhbHVlKSxcbiAgICAgICAgICAgICAgLyogU0FGRVRZOiBBUEkg642w7L2U66CI7J207YSw7JmAIFpvZCDqsoDspp3quLAg65Ox66GdIOqzhOyVveydtCDsnbQg6rCS7J2YIO2DgOyeheydhCDrs7TsnqXtlZzri6QuICovIHRpbWV6b25lIGFzIGAke3N0cmluZ30vJHtzdHJpbmd9YCxcbiAgICAgICAgICAgICAgREFURV9GT1JNQVQsXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgICAvLyBUaW1lem9uZSDroZzqt7jripQgcHJpbnRTdGFydHVwU3VtbWFyeeyXkOyEnCDthrXtlakg7Lac66ClXG4gICAgfVxuXG4gICAgLy8g7KCE7LK0IOudvOyasO2MhSDrpqzsiqTtirhcbiAgICBzZXJ2ZXIuZ2V0KFxuICAgICAgYCR7dGhpcy5jb25maWcuYXBpLnJvdXRlLnByZWZpeH0vcm91dGVzYCxcbiAgICAgIGFzeW5jIChfcmVxdWVzdCwgX3JlcGx5KTogUHJvbWlzZTx0eXBlb2YgdGhpcy5zeW5jZXIuYXBpcz4gPT4ge1xuICAgICAgICByZXR1cm4gdGhpcy5zeW5jZXIuYXBpcztcbiAgICAgIH0sXG4gICAgKTtcblxuICAgIC8vIEhlYWx0aGNoZWNrIEFQSVxuICAgIHNlcnZlci5nZXQoXG4gICAgICBgJHt0aGlzLmNvbmZpZy5hcGkucm91dGUucHJlZml4fS9oZWFsdGhjaGVja2AsXG4gICAgICBhc3luYyAoX3JlcXVlc3QsIF9yZXBseSk6IFByb21pc2U8c3RyaW5nPiA9PiB7XG4gICAgICAgIHJldHVybiBcIm9rXCI7XG4gICAgICB9LFxuICAgICk7XG5cbiAgICAvLyBTb25hbXUgVUkgQVBJICjroZzsu6wg7ZmY6rK97JeQ7ISc66eMKVxuICAgIGNvbnN0IHsgaXNMb2NhbCB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vdXRpbHMvY29udHJvbGxlclwiKTtcbiAgICBpZiAoaXNMb2NhbCgpKSB7XG4gICAgICBjb25zdCB7IHNvbmFtdVVJQXBpUGx1Z2luIH0gPSBhd2FpdCBpbXBvcnQoXCIuLi91aS9hcGlcIik7XG4gICAgICBzZXJ2ZXIucmVnaXN0ZXIoc29uYW11VUlBcGlQbHVnaW4pO1xuICAgIH1cblxuICAgIC8vIERldlJ1bm5lciDthYzsiqTtirgg7JeU65Oc7Y+s7J247Yq4ICjroZzsu6wg7ZmY6rK9ICsgZGV2UnVubmVyIO2ZnOyEse2ZlCDsi5wpXG4gICAgaWYgKGlzTG9jYWwoKSAmJiB0aGlzLmNvbmZpZy50ZXN0Py5kZXZSdW5uZXI/LmVuYWJsZWQpIHtcbiAgICAgIGNvbnN0IHsgcmVnaXN0ZXJEZXZUZXN0Um91dGVzIH0gPSBhd2FpdCBpbXBvcnQoXCIuLi90ZXN0aW5nL2Rldi10ZXN0LXJvdXRlc1wiKTtcbiAgICAgIGF3YWl0IHJlZ2lzdGVyRGV2VGVzdFJvdXRlcyhzZXJ2ZXIsIHRoaXMuY29uZmlnLnRlc3QuZGV2UnVubmVyKTtcbiAgICB9XG5cbiAgICBjb25zdCB3ZWJQYXRoID0gcGF0aC5qb2luKHRoaXMuYXBwUm9vdFBhdGgsIFwid2ViXCIpO1xuICAgIGNvbnN0IGhhc1dlYiA9IGF3YWl0IGV4aXN0cyh3ZWJQYXRoKTtcblxuICAgIC8vIOyghOyXrSBjb21wcmVzcyDsmLXshZgg6rOE7IKwIChyb3V0ZS5jb21wcmVzczogdHJ1ZeydvCDrlYwg7IKs7JqpKVxuICAgIGNvbnN0IHBsdWdpbkNvbXByZXNzID0gdGhpcy5jb25maWcuc2VydmVyLnBsdWdpbnM/LmNvbXByZXNzO1xuICAgIGNvbnN0IGdsb2JhbENvbXByZXNzT3B0aW9uczogQ29tcHJlc3NPcHRpb25zIHwgdW5kZWZpbmVkID0gcGx1Z2luQ29tcHJlc3NcbiAgICAgID8gcGx1Z2luQ29tcHJlc3MgPT09IHRydWVcbiAgICAgICAgPyB7IHRocmVzaG9sZDogMTAyNCwgZW5jb2RpbmdzOiBbXCJiclwiLCBcImd6aXBcIiwgXCJkZWZsYXRlXCJdIH1cbiAgICAgICAgOiB7XG4gICAgICAgICAgICB0aHJlc2hvbGQ6IHBsdWdpbkNvbXByZXNzLnRocmVzaG9sZCxcbiAgICAgICAgICAgIGVuY29kaW5nczogcGx1Z2luQ29tcHJlc3MuZW5jb2RpbmdzLFxuICAgICAgICAgICAgY3VzdG9tVHlwZXM6IHBsdWdpbkNvbXByZXNzLmN1c3RvbVR5cGVzLFxuICAgICAgICAgIH1cbiAgICAgIDogdW5kZWZpbmVkO1xuXG4gICAgaWYgKGlzTG9jYWwoKSkge1xuICAgICAgLy8g66Gc7LusIOqwnOuwnCDtmZjqsr06IGNhdGNoLWFsbOuhnCBBUEnrpbwg64+Z7KCBIOunpOy5re2VmOyXrCBITVLsnYQg7KeA7JuQ7ZWp64uI64ukLlxuICAgICAgLy8gU09OQU1VX0RJU0FCTEVfSU5URUdSQVRFRF9XRUI9eWVz66GcIOyEpOygle2VmOuptCBkZXZfYXBpIOuqqOuTnOyXkOyEnCBWaXRlIO2Gte2VqeydhCDruYTtmZzshLHtmZTtlaAg7IiYIOyeiOyKteuLiOuLpC5cbiAgICAgIGNvbnN0IGRpc2FibGVJbnRlZ3JhdGVkV2ViID0gcHJvY2Vzcy5lbnYuU09OQU1VX0RJU0FCTEVfSU5URUdSQVRFRF9XRUIgPT09IFwieWVzXCI7XG4gICAgICBpZiAoaGFzV2ViICYmICFkaXNhYmxlSW50ZWdyYXRlZFdlYikge1xuICAgICAgICBhd2FpdCB0aGlzLnNldHVwRGV2U2VydmVyV2l0aFZpdGUoc2VydmVyLCB3ZWJQYXRoLCBjb25maWcpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5zZXR1cERldlNlcnZlcihzZXJ2ZXIsIGNvbmZpZyk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIO2UhOuhnOuNleyFmCDtmZjqsr06IOqwnOuzhCBBUEkg65287Jqw7Yq4ICsg7KCV7KCBIO2MjOydvCDshJzruZlcbiAgICAgIGZvciAoY29uc3QgYXBpIG9mIHRoaXMuc3luY2VyLmFwaXMpIHtcbiAgICAgICAgaWYgKHRoaXMuc3luY2VyLm1vZGVsc1thcGkubW9kZWxOYW1lXSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGDsoJXsnZjrkJjsp4Ag7JWK7J2AIOuqqOuNuOyXkCDsoJHqt7wgJHthcGkubW9kZWxOYW1lfWApO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQHdlYnNvY2tldCByb3V0ZeuKlCB3c0hhbmRsZXLroZwg65Ox66Gd7ZWY6rOgLCDqsJnsnYAgcGF0aOydmCDsnbzrsJggSFRUUCBHRVTsnYAgNDI2IOydkeuLteycvOuhnCB1cGdyYWRl66W8IOqwleygnO2VqFxuICAgICAgICBpZiAoYXBpLndlYnNvY2tldE9wdGlvbnMpIHtcbiAgICAgICAgICBzZXJ2ZXIucm91dGUoe1xuICAgICAgICAgICAgbWV0aG9kOiBcIkdFVFwiLFxuICAgICAgICAgICAgdXJsOiB0aGlzLmNvbmZpZy5hcGkucm91dGUucHJlZml4ICsgYXBpLnBhdGgsXG4gICAgICAgICAgICBoYW5kbGVyOiB0aGlzLmNyZWF0ZVdlYlNvY2tldFVwZ3JhZGVSZXF1aXJlZEhhbmRsZXIoKSxcbiAgICAgICAgICAgIHdzSGFuZGxlcjogdGhpcy5jcmVhdGVXZWJTb2NrZXRIYW5kbGVyKGFwaSwgY29uZmlnKSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHNlcnZlci5yb3V0ZSh7XG4gICAgICAgICAgbWV0aG9kOiBhcGkub3B0aW9ucy5odHRwTWV0aG9kID8/IFwiR0VUXCIsXG4gICAgICAgICAgdXJsOiB0aGlzLmNvbmZpZy5hcGkucm91dGUucHJlZml4ICsgYXBpLnBhdGgsXG4gICAgICAgICAgaGFuZGxlcjogYXdhaXQgdGhpcy5jcmVhdGVBcGlIYW5kbGVyKGFwaSwgY29uZmlnKSxcbiAgICAgICAgICBjb21wcmVzczogdG9GYXN0aWZ5Q29tcHJlc3NPcHRpb24oYXBpLm9wdGlvbnMuY29tcHJlc3MsIGdsb2JhbENvbXByZXNzT3B0aW9ucyksXG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICAvLyDtlITroZzrjZXshZjsl5DshJzripQgd2ViIOyGjOyKpChhcHBSb290L3dlYikg7Jyg66y07JmAIOustOq0gO2VmOqyjCxcbiAgICAgIC8vIGFwaS93ZWItZGlzdCDsobTsnqwg7Jes67aA66W8IHNldHVwU3RhdGljV2ViU2VydmVyIOuCtOu2gOyXkOyEnCDtjJDri6jtlanri4jri6QuXG4gICAgICBhd2FpdCB0aGlzLnNldHVwU3RhdGljV2ViU2VydmVyKHNlcnZlciwgY29uZmlnLCBnbG9iYWxDb21wcmVzc09wdGlvbnMpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBkZXYg66qo65OcIOqzte2GtTogY2F0Y2gtYWxs7JeQ7IScIOuniOyngOuniSDspIDruYQg7JmE66OMIEFQSSBzbmFwc2hvdOydhCDtg5Dsg4ntlZjsl6wg7JqU7LKt7J2EIOyymOumrO2VqeuLiOuLpC5cbiAgICogc2VydmVyLnJvdXRlKCnroZwg6rCc67OEIOuTseuhne2VmOuptCBoYW5kbGVy6rCAIOqzoOygleuQmOyWtCBITVLsnbQg64+Z7J6R7ZWY7KeAIOyViuycvOuvgOuhnCxcbiAgICogcmVmcmVzaCDshLHqs7Ug7IucIOq1kOyytOuQmOuKlCBzbmFwc2hvdOydhCDrp6Qg7JqU7LKtIOyhsO2ajO2VqeuLiOuLpC5cbiAgICpcbiAgICog7JqU7LKt7J20IC9hcGko7KCV7ZmV7Z6I64qUIHRoaXMuY29uZmlnLmFwaS5yb3V0ZS5wcmVmaXgp66GcIOyLnOyeke2VmOyngCDslYrripQg6rK97Jqw652866m0IG51bGzsnYQg67CY7ZmY7ZWY66mwIOuBneuDheuLiOuLpC5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgaGFuZGxlRGV2QXBpUmVxdWVzdChcbiAgICByZXF1ZXN0OiBGYXN0aWZ5UmVxdWVzdCxcbiAgICBjb25maWc6IFNvbmFtdUZhc3RpZnlDb25maWcsXG4gICk6IFByb21pc2U8KChyZXF1ZXN0OiBGYXN0aWZ5UmVxdWVzdCwgcmVwbHk6IEZhc3RpZnlSZXBseSkgPT4gUHJvbWlzZTxBcGlNZXRob2RSZXN1bHQ+KSB8IG51bGw+IHtcbiAgICBjb25zdCBtYXRjaGVkQXBpID0gdGhpcy5maW5kTWF0Y2hlZEFwaShyZXF1ZXN0LCB0aGlzLnByZXBhcmVkQXBpcywgdGhpcy5wcmVwYXJlZE1vZGVscyk7XG5cbiAgICBpZiAoIW1hdGNoZWRBcGkpIHtcbiAgICAgIHRocm93IG5ldyBOb3RGb3VuZEV4Y2VwdGlvbihTRChcImVycm9yLmFwaS5ub3RGb3VuZFwiKSk7XG4gICAgfVxuXG4gICAgLy8gd2Vic29ja2V0IHJvdXRl66W8IOydvOuwmCBIVFRQ66GcIOyngeygkSDtmLjstpztlZwg6rK97JqwIDQyNuydhCDrj4zroKTspJggdXBncmFkZSDsl4bsnbQg7KCR6re87ZWY64qUIOqyg+ydhCDssKjri6jtlahcbiAgICBpZiAobWF0Y2hlZEFwaS53ZWJzb2NrZXRPcHRpb25zKSB7XG4gICAgICByZXR1cm4gdGhpcy5jcmVhdGVXZWJTb2NrZXRVcGdyYWRlUmVxdWlyZWRIYW5kbGVyKCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGF3YWl0IHRoaXMuY3JlYXRlQXBpSGFuZGxlcihtYXRjaGVkQXBpLCBjb25maWcsIHRoaXMucHJlcGFyZWRNb2RlbHMpO1xuICB9XG5cbiAgcHJpdmF0ZSBmaW5kTWF0Y2hlZEFwaShcbiAgICByZXF1ZXN0OiBGYXN0aWZ5UmVxdWVzdCxcbiAgICBhcGlzOiByZWFkb25seSBFeHRlbmRlZEFwaVtdLFxuICAgIG1vZGVsczogTG9hZGVkTW9kZWxzLFxuICApOiBFeHRlbmRlZEFwaSB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3QgdXJsID0gdGhpcy5nZXRQYXRobmFtZUZyb21VcmwocmVxdWVzdC51cmwpO1xuICAgIGNvbnN0IG1ldGhvZCA9IHJlcXVlc3QubWV0aG9kO1xuXG4gICAgaWYgKCF1cmwuc3RhcnRzV2l0aCh0aGlzLmNvbmZpZy5hcGkucm91dGUucHJlZml4KSkge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICByZXR1cm4gYXBpcy5maW5kKChhcGkpID0+IHtcbiAgICAgIGlmIChtb2RlbHNbYXBpLm1vZGVsTmFtZV0gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICBjb25zdCBhcGlNZXRob2QgPSBhcGkub3B0aW9ucy5odHRwTWV0aG9kID8/IFwiR0VUXCI7XG4gICAgICBpZiAoYXBpTWV0aG9kICE9PSBtZXRob2QpIHJldHVybiBmYWxzZTtcblxuICAgICAgY29uc3QgZnVsbFBhdGggPSB0aGlzLmNvbmZpZy5hcGkucm91dGUucHJlZml4ICsgYXBpLnBhdGg7XG4gICAgICByZXR1cm4gdGhpcy5pc1BhdGhQYXR0ZXJuTWF0Y2goZnVsbFBhdGgsIHVybCk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogZGV2IGFwaSDrqqjrk5w6IFZpdGUg7JeG7J20IEFQSSDrj5nsoIEg65287Jqw7YyF66eMIOygnOqzte2VqeuLiOuLpC5cbiAgICogSE1S7J2EIOychO2VtCBjYXRjaC1hbGzsl5DshJwg66ekIOyalOyyreuniOuLpCDspIDruYQg7JmE66OMIEFQSSBzbmFwc2hvdOydhCDsobDtmoztlanri4jri6QuXG4gICAqL1xuICBwcml2YXRlIHNldHVwRGV2U2VydmVyKFxuICAgIHNlcnZlcjogRmFzdGlmeUluc3RhbmNlPFNlcnZlciwgSW5jb21pbmdNZXNzYWdlLCBTZXJ2ZXJSZXNwb25zZT4sXG4gICAgY29uZmlnOiBTb25hbXVGYXN0aWZ5Q29uZmlnLFxuICApOiB2b2lkIHtcbiAgICAvLyB1cGdyYWRl64qUIOyLpOyniOyggeycvOuhnCBHRVTsl5DshJzrp4wg7ISx66a97ZWY66+A66GcIEdFVCArIHdzSGFuZGxlciDsmYAg6re4IOyZuCBtZXRob2Trpbwg67OE64+EIHJvdXRl66GcIOu2hOumrO2VqFxuICAgIHNlcnZlci5yb3V0ZSh7XG4gICAgICBtZXRob2Q6IFwiR0VUXCIsXG4gICAgICB1cmw6IGAke3RoaXMuY29uZmlnLmFwaS5yb3V0ZS5wcmVmaXh9LypgLFxuICAgICAgaGFuZGxlcjogYXN5bmMgKHJlcXVlc3QsIHJlcGx5KSA9PiB7XG4gICAgICAgIGNvbnN0IGhhbmRsZXIgPSBhd2FpdCB0aGlzLmhhbmRsZURldkFwaVJlcXVlc3QocmVxdWVzdCwgY29uZmlnKTtcbiAgICAgICAgaWYgKGhhbmRsZXIpIHtcbiAgICAgICAgICByZXR1cm4gaGFuZGxlcihyZXF1ZXN0LCByZXBseSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8g65Ox66Gd65CcIEFQSeyZgCDsnbzsuZjtlZjsp4Ag7JWK64qUIOyalOyyreyXkCDrjIDtlZwgZmFsbGJhY2vsnoXri4jri6QuXG4gICAgICAgIHRocm93IG5ldyBOb3RGb3VuZEV4Y2VwdGlvbihTRChcImVycm9yLmFwaS5ub3RGb3VuZFwiKSk7XG4gICAgICB9LFxuICAgICAgd3NIYW5kbGVyOiBhc3luYyAoY29ubmVjdGlvbiwgcmVxdWVzdCkgPT4ge1xuICAgICAgICBhd2FpdCB0aGlzLmhhbmRsZURldldlYlNvY2tldFJlcXVlc3QoY29ubmVjdGlvbi5zb2NrZXQsIHJlcXVlc3QsIGNvbmZpZyk7XG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgc2VydmVyLnJvdXRlKHtcbiAgICAgIG1ldGhvZDogW1wiSEVBRFwiLCBcIlBPU1RcIiwgXCJQVVRcIiwgXCJERUxFVEVcIiwgXCJQQVRDSFwiXSxcbiAgICAgIHVybDogYCR7dGhpcy5jb25maWcuYXBpLnJvdXRlLnByZWZpeH0vKmAsXG4gICAgICBoYW5kbGVyOiBhc3luYyAocmVxdWVzdCwgcmVwbHkpID0+IHtcbiAgICAgICAgY29uc3QgaGFuZGxlciA9IGF3YWl0IHRoaXMuaGFuZGxlRGV2QXBpUmVxdWVzdChyZXF1ZXN0LCBjb25maWcpO1xuICAgICAgICBpZiAoaGFuZGxlcikge1xuICAgICAgICAgIHJldHVybiBoYW5kbGVyKHJlcXVlc3QsIHJlcGx5KTtcbiAgICAgICAgfVxuICAgICAgICB0aHJvdyBuZXcgTm90Rm91bmRFeGNlcHRpb24oU0QoXCJlcnJvci5hcGkubm90Rm91bmRcIikpO1xuICAgICAgfSxcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgdml0ZVNlcnZlcjogYW55ID0gbnVsbDtcblxuICAvKipcbiAgICogZGV2IGFsbCDrqqjrk5w6IFZpdGUgRGV2IFNlcnZlcuulvCDthrXtlantlZjsl6wgQVBJICsgU1NSICsgQ1NS7J2EIOuqqOuRkCDsoJzqs7Xtlanri4jri6QuXG4gICAqIEFQSSDrj5nsoIEg66ek7Lmt7J2AIGhhbmRsZURldkFwaVJlcXVlc3Trpbwg6rO17Jyg7ZWp64uI64ukLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBzZXR1cERldlNlcnZlcldpdGhWaXRlKFxuICAgIHNlcnZlcjogRmFzdGlmeUluc3RhbmNlPFNlcnZlciwgSW5jb21pbmdNZXNzYWdlLCBTZXJ2ZXJSZXNwb25zZT4sXG4gICAgd2ViUGF0aDogc3RyaW5nLFxuICAgIGNvbmZpZzogU29uYW11RmFzdGlmeUNvbmZpZyxcbiAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgLy8gQGZhc3RpZnkvbWlkZGllIOuTseuhnSAoQ29ubmVjdC1zdHlsZSBtaWRkbGV3YXJlIOyngOybkClcbiAgICBhd2FpdCBzZXJ2ZXIucmVnaXN0ZXIoKGF3YWl0IGltcG9ydChcIkBmYXN0aWZ5L21pZGRpZVwiKSkuZGVmYXVsdCk7XG5cbiAgICBjb25zdCB2aXRlID0gYXdhaXQgaW1wb3J0KFwidml0ZVwiKTtcbiAgICAvLyBAZmFzdGlmeS93ZWJzb2NrZXQg7ZSM65+s6re47J247J20IO2ZnOyEse2ZlOuQmOuptCBITVIgd2Vic29ja2V06rO8IHNlcnZlciBzb2NrZXTsnbQg7Lap64+M7ZWY66+A66GcIGRlZGljYXRlZCDtj6ztirjroZwg67aE66as7ZWoXG4gICAgY29uc3QgcmVxdWlyZXNEZWRpY2F0ZWRIbXJTZXJ2ZXIgPSBCb29sZWFuKHRoaXMuY29uZmlnLnNlcnZlci5wbHVnaW5zPy53cyk7XG4gICAgY29uc3QgaG1yID0gcmVzb2x2ZUludGVncmF0ZWRWaXRlSG1yT3B0aW9ucyh7XG4gICAgICBodHRwU2VydmVyOiBzZXJ2ZXIuc2VydmVyLFxuICAgICAgcmVxdWlyZXNEZWRpY2F0ZWRXZWJTb2NrZXRTZXJ2ZXI6IHJlcXVpcmVzRGVkaWNhdGVkSG1yU2VydmVyLFxuICAgIH0pO1xuXG4gICAgdGhpcy52aXRlU2VydmVyID0gYXdhaXQgdml0ZS5jcmVhdGVTZXJ2ZXIoe1xuICAgICAgcm9vdDogd2ViUGF0aCxcbiAgICAgIHNlcnZlcjoge1xuICAgICAgICBtaWRkbGV3YXJlTW9kZTogdHJ1ZSxcbiAgICAgICAgaG1yLFxuICAgICAgfSxcbiAgICAgIGFwcFR5cGU6IFwiY3VzdG9tXCIsXG4gICAgfSk7XG5cbiAgICAvLyBWaXRlIG1pZGRsZXdhcmUg65Ox66GdIChWaXRlIOyXkOyFiyDsspjrpqwpXG4gICAgc2VydmVyLnVzZSgocmVxLCByZXMsIG5leHQpID0+IHtcbiAgICAgIC8vIEFQSeyZgCBTb25hbXUgVUnripQgRmFzdGlmeSDrnbzsmrDtirjqsIAg7LKY66as7ZWY64+E66GdIHNraXBcbiAgICAgIGlmIChyZXEudXJsPy5zdGFydHNXaXRoKHRoaXMuY29uZmlnLmFwaS5yb3V0ZS5wcmVmaXgpIHx8IHJlcS51cmw/LnN0YXJ0c1dpdGgoXCIvc29uYW11LXVpXCIpKSB7XG4gICAgICAgIHJldHVybiBuZXh0KCk7XG4gICAgICB9XG4gICAgICAvLyDrgpjrqLjsp4DripQgVml0ZSBtaWRkbGV3YXJl66GcIOyghOuLrFxuICAgICAgcmV0dXJuIHRoaXMudml0ZVNlcnZlci5taWRkbGV3YXJlcyhyZXEsIHJlcywgbmV4dCk7XG4gICAgfSk7XG5cbiAgICAvLyBXUyB1cGdyYWRlIOqyveuhnChHRVQp7JmAIOydvOuwmCBIVFRQIOuplOyEnOuTnOulvCDrs4Trj4Qgcm91dGXroZwg67aE66as7ZW0IHdlYnNvY2tldCByb3V0ZeqwgCBIVE1MIGZhbGxiYWNr7JeQIOuoue2eiOyngCDslYrrj4TroZ0g7ZWoXG4gICAgc2VydmVyLnJvdXRlKHtcbiAgICAgIG1ldGhvZDogXCJHRVRcIixcbiAgICAgIHVybDogYCR7dGhpcy5jb25maWcuYXBpLnJvdXRlLnByZWZpeH0vKmAsXG4gICAgICBoYW5kbGVyOiBhc3luYyAocmVxdWVzdCwgcmVwbHkpID0+IHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdGhpcy5oYW5kbGVEZXZBcGlSZXF1ZXN0KHJlcXVlc3QsIGNvbmZpZyk7XG4gICAgICAgIGlmIChyZXN1bHQpIHtcbiAgICAgICAgICByZXR1cm4gcmVzdWx0KHJlcXVlc3QsIHJlcGx5KTtcbiAgICAgICAgfVxuICAgICAgICB0aHJvdyBuZXcgTm90Rm91bmRFeGNlcHRpb24oU0QoXCJlcnJvci5hcGkubm90Rm91bmRcIikpO1xuICAgICAgfSxcbiAgICAgIHdzSGFuZGxlcjogYXN5bmMgKGNvbm5lY3Rpb24sIHJlcXVlc3QpID0+IHtcbiAgICAgICAgYXdhaXQgdGhpcy5oYW5kbGVEZXZXZWJTb2NrZXRSZXF1ZXN0KGNvbm5lY3Rpb24uc29ja2V0LCByZXF1ZXN0LCBjb25maWcpO1xuICAgICAgfSxcbiAgICB9KTtcblxuICAgIHNlcnZlci5yb3V0ZSh7XG4gICAgICBtZXRob2Q6IFtcIkhFQURcIiwgXCJQT1NUXCIsIFwiUFVUXCIsIFwiREVMRVRFXCIsIFwiUEFUQ0hcIl0sXG4gICAgICB1cmw6IGAke3RoaXMuY29uZmlnLmFwaS5yb3V0ZS5wcmVmaXh9LypgLFxuICAgICAgaGFuZGxlcjogYXN5bmMgKHJlcXVlc3QsIHJlcGx5KSA9PiB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMuaGFuZGxlRGV2QXBpUmVxdWVzdChyZXF1ZXN0LCBjb25maWcpO1xuICAgICAgICBpZiAocmVzdWx0KSB7XG4gICAgICAgICAgcmV0dXJuIHJlc3VsdChyZXF1ZXN0LCByZXBseSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgbmV3IE5vdEZvdW5kRXhjZXB0aW9uKFNEKFwiZXJyb3IuYXBpLm5vdEZvdW5kXCIpKTtcbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICAvLyBjYXRjaC1hbGwg65287Jqw7Yq47JeQ7IScIFNTUi9DU1Ig7LKY66asXG4gICAgLy8g6rCc67CcIO2ZmOqyveyXkOyEnOuKlCDrnbzsmrDtirjrs4QgY29tcHJlc3Mg7Ji17IWY7J2EIO2PrOq4sO2VmOqzoCBITVIg7J207KCQ7J2EIOy3qO2VqeuLiOuLpC5cbiAgICBzZXJ2ZXIucm91dGUoe1xuICAgICAgbWV0aG9kOiBbXCJHRVRcIiwgXCJIRUFEXCJdLFxuICAgICAgdXJsOiBcIi8qXCIsXG4gICAgICBoYW5kbGVyOiBhc3luYyAocmVxdWVzdCwgcmVwbHkpID0+IHtcbiAgICAgICAgY29uc3QgdXJsID0gcmVxdWVzdC51cmw7XG5cbiAgICAgICAgLy8gMS4gU1NSIOudvOyasO2KuCDsspjrpqxcbiAgICAgICAgY29uc3QgeyBtYXRjaFNTUlJvdXRlLCByZW5kZXJTU1IgfSA9IGF3YWl0IGltcG9ydChcIi4uL3NzclwiKTtcbiAgICAgICAgY29uc3Qgc3NyTWF0Y2ggPSBtYXRjaFNTUlJvdXRlKHVybCk7XG4gICAgICAgIGlmIChzc3JNYXRjaCkge1xuICAgICAgICAgIGNvbnNvbGUubG9nKGBbU1NSXSBNYXRjaGVkIHJvdXRlOiAke3Nzck1hdGNoLnJvdXRlLnBhdGh9YCk7XG4gICAgICAgICAgY29uc3QgaHRtbCA9IGF3YWl0IHJlbmRlclNTUihcbiAgICAgICAgICAgIHVybCxcbiAgICAgICAgICAgIHNzck1hdGNoLnJvdXRlLFxuICAgICAgICAgICAgc3NyTWF0Y2gucGFyYW1zLFxuICAgICAgICAgICAgcmVxdWVzdCxcbiAgICAgICAgICAgIHJlcGx5LFxuICAgICAgICAgICAgY29uZmlnLFxuICAgICAgICAgICAgdGhpcy52aXRlU2VydmVyLFxuICAgICAgICAgICk7XG4gICAgICAgICAgcmVwbHkudHlwZShcInRleHQvaHRtbFwiKTtcbiAgICAgICAgICByZXR1cm4gaHRtbDtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIDIuIENTUiBmYWxsYmFja1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGxldCB0ZW1wbGF0ZSA9IGF3YWl0IGZzLnJlYWRGaWxlKFxuICAgICAgICAgICAgcGF0aC5qb2luKHRoaXMudml0ZVNlcnZlci5jb25maWcucm9vdCwgXCJpbmRleC5odG1sXCIpLFxuICAgICAgICAgICAgXCJ1dGYtOFwiLFxuICAgICAgICAgICk7XG4gICAgICAgICAgdGVtcGxhdGUgPSBhd2FpdCB0aGlzLnZpdGVTZXJ2ZXIudHJhbnNmb3JtSW5kZXhIdG1sKHVybCwgdGVtcGxhdGUpO1xuXG4gICAgICAgICAgLy8gP2htcj1mYWxzZeuhnCDsl7Ag7Y6Y7J207KeA64qUIEhNUiDsm7nshozsvJPrp4wg64GK7Ja0IOyDiOuhnOqzoOy5qOuQmOyngCDslYrqsowg7ZWc64ukLlxuICAgICAgICAgIGNvbnN0IHsgSE1SX09QVF9PVVRfU0NSSVBULCBpc0htckRpc2FibGVkQnlRdWVyeSB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vc3NyL2htci1vcHQtb3V0XCIpO1xuICAgICAgICAgIGlmIChpc0htckRpc2FibGVkQnlRdWVyeSh1cmwpKSB7XG4gICAgICAgICAgICB0ZW1wbGF0ZSA9IHRlbXBsYXRlLnJlcGxhY2UoXCI8aGVhZD5cIiwgYDxoZWFkPlxcbiR7SE1SX09QVF9PVVRfU0NSSVBUfWApO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHJlcGx5LnR5cGUoXCJ0ZXh0L2h0bWxcIik7XG4gICAgICAgICAgcmV0dXJuIHRlbXBsYXRlO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgdGhpcy52aXRlU2VydmVyLnNzckZpeFN0YWNrdHJhY2UoXG4gICAgICAgICAgICAvKiBTQUZFVFk6IEFQSSDrjbDsvZTroIjsnbTthLDsmYAgWm9kIOqygOymneq4sCDrk7HroZ0g6rOE7JW97J20IOydtCDqsJLsnZgg7YOA7J6F7J2EIOuztOyepe2VnOuLpC4gKi8gZSBhcyBFcnJvcixcbiAgICAgICAgICApO1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZSk7XG4gICAgICAgICAgcmVwbHkuc3RhdHVzKDUwMCk7XG4gICAgICAgICAgcmV0dXJuIC8qIFNBRkVUWTogQVBJIOuNsOy9lOugiOydtO2EsOyZgCBab2Qg6rKA7Kad6riwIOuTseuhnSDqs4Tslb3snbQg7J20IOqwkuydmCDtg4DsnoXsnYQg67O07J6l7ZWc64ukLiAqLyAoXG4gICAgICAgICAgICBlIGFzIEVycm9yXG4gICAgICAgICAgKS5tZXNzYWdlO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgLy8g7ISc67KEIOyiheujjCDsi5wgVml0ZeuPhCDsooXro4xcbiAgICBzZXJ2ZXIuYWRkSG9vayhcIm9uQ2xvc2VcIiwgYXN5bmMgKCkgPT4ge1xuICAgICAgYXdhaXQgdGhpcy52aXRlU2VydmVyLmNsb3NlKCk7XG4gICAgfSk7XG5cbiAgICBpZiAoXCJwb3J0XCIgaW4gaG1yKSB7XG4gICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgY2hhbGsuZGltKFxuICAgICAgICAgIGDinJMgVml0ZSBITVIgdXNpbmcgZGVkaWNhdGVkIHdlYnNvY2tldCBwb3J0ICR7aG1yLnBvcnR9IHRvIGF2b2lkIEZhc3RpZnkgd2Vic29ja2V0IGNvbmZsaWN0c2AsXG4gICAgICAgICksXG4gICAgICApO1xuICAgIH1cbiAgICBjb25zb2xlLmxvZyhjaGFsay5kaW0oXCLinJMgVml0ZSBkZXYgc2VydmVyIGludGVncmF0ZWRcIikpO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBzZXR1cFN0YXRpY1dlYlNlcnZlcihcbiAgICBzZXJ2ZXI6IEZhc3RpZnlJbnN0YW5jZTxTZXJ2ZXIsIEluY29taW5nTWVzc2FnZSwgU2VydmVyUmVzcG9uc2U+LFxuICAgIGNvbmZpZzogU29uYW11RmFzdGlmeUNvbmZpZyxcbiAgICBnbG9iYWxDb21wcmVzc09wdGlvbnM6IENvbXByZXNzT3B0aW9ucyB8IHVuZGVmaW5lZCxcbiAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgLy8g6rK966GcIOuqhe2Zle2ZlDogYXBpL3dlYi1kaXN0L2NsaWVudCAo7KCV7KCBIO2MjOydvCksIGFwaS93ZWItZGlzdC9zZXJ2ZXIgKFNTUiBlbnRyeSksIGFwaS9kaXN0L3NzciAoU1NSIHJvdXRlcyAtIEFQSSDshozsnKApXG4gICAgY29uc3Qgd2ViRGlzdFBhdGggPSBwYXRoLmpvaW4odGhpcy5hcGlSb290UGF0aCwgXCJ3ZWItZGlzdFwiLCBcImNsaWVudFwiKTtcbiAgICBjb25zdCBzc3JQYXRoID0gcGF0aC5qb2luKHRoaXMuYXBpUm9vdFBhdGgsIFwid2ViLWRpc3RcIiwgXCJzZXJ2ZXJcIik7XG4gICAgY29uc3Qgc3NyRW50cnlQYXRoID0gcGF0aC5qb2luKHNzclBhdGgsIFwiZW50cnktc2VydmVyLmdlbmVyYXRlZC5qc1wiKTtcbiAgICBjb25zdCBzc3JSb3V0ZXNQYXRoID0gcGF0aC5qb2luKHRoaXMuYXBpUm9vdFBhdGgsIFwiZGlzdFwiLCBcInNzclwiLCBcInJvdXRlcy5qc1wiKTtcblxuICAgIGlmICghKGF3YWl0IGV4aXN0cyh3ZWJEaXN0UGF0aCkpKSB7XG4gICAgICBjb25zb2xlLndhcm4oYOKaoCBXZWIgZGlzdCBub3QgZm91bmQ6ICR7d2ViRGlzdFBhdGh9YCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gU1NSIGVudHJ5IOyhtOyerCDsl6zrtoAg7ZmV7J24XG4gICAgY29uc3Qgc3NyQXZhaWxhYmxlID0gYXdhaXQgZXhpc3RzKHNzckVudHJ5UGF0aCk7XG5cbiAgICBpZiAoIXNzckF2YWlsYWJsZSkge1xuICAgICAgY29uc29sZS53YXJuKGDimqAgU1NSIGVudHJ5IG5vdCBmb3VuZDogJHtzc3JFbnRyeVBhdGh9YCk7XG4gICAgICBjb25zb2xlLndhcm4oXCIgIFNTUiB3aWxsIGJlIGRpc2FibGVkLiBPbmx5IENTUiB3aWxsIHdvcmsuXCIpO1xuICAgIH1cblxuICAgIC8vIFNTUiDrnbzsmrDtirgg66Gc65OcIChwcm9kdWN0aW9u7JeQ7ISc66eMLCDsgqzsmqnsnpAg7ZSE66Gc7KCd7Yq47J2YIHNzci9yb3V0ZXMudHMpXG4gICAgaWYgKHNzckF2YWlsYWJsZSkge1xuICAgICAgaWYgKGF3YWl0IGV4aXN0cyhzc3JSb3V0ZXNQYXRoKSkge1xuICAgICAgICAvLyB0cy1sb2FkZXLrnbzrqbQgXCJmaWxlOi8vXCLroZwg7Iuc7J6R7ZWY64qUIGZ1bGx5LXJlc29sdmVkIHBhdGjrp4wg67Cb6riw7JeQIOydtOulvCDsspjrpqztlbTso7zripQgaW1wb3J0TWVtYmVyc+ulvCDsgqzsmqntlbTslbwg7ZaI6rKg7KeA66eMLFxuICAgICAgICAvLyDsl6zquLDripQg7ZSE66Gc642V7IWYIO2ZmOqyveyXkOyEnCBsb2FkZXIg7JeG7J20IOuPjOyVhOqwgOq4sCDrlYzrrLjsl5AgXCLsp4Tsp5wganMg7YyM7J28XCLsnZggXCLqt7jrg6VcIiDsoIjrjIDqsr3roZzrpbwg67CU66GcIGltcG9ydO2VtOuPhCDrkKnri4jri6QuXG4gICAgICAgIC8vIOydtCDrgrTsmqnsnYAg7J20IO2VqOyImCDrgrTsl5DshJwg7JWE656Y7JeQIOuCmOyYrCDri6TrpbggaW1wb3J0IO2YuOy2nOyXkOuPhCDrj5nsnbztlZjqsowg7KCB7Jqp65Cp64uI64ukLlxuICAgICAgICBhd2FpdCBpbXBvcnQoc3NyUm91dGVzUGF0aCk7XG4gICAgICAgIGNvbnNvbGUubG9nKFwi4pyTIFNTUiByb3V0ZXMgbG9hZGVkXCIpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc29sZS53YXJuKGDimqAgU1NSIHJvdXRlcyBub3QgZm91bmQ6ICR7c3NyUm91dGVzUGF0aH1gKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyDroaTrp4Eg7JeF642w7J207Yq4IOuMgOydkTogYXNzZXQgaGFzaCDrtojsnbzsuZgg7IucIO2YhOyerCDrsoTsoIQg7KeB7KCRIOyEnOu5mVxuICAgIHNlcnZlci5nZXQoXCIvYXNzZXRzLzpmaWxlbmFtZVwiLCBhc3luYyAocmVxdWVzdCwgcmVwbHkpID0+IHtcbiAgICAgIGNvbnN0IHJlcXVlc3RlZEZpbGUgPVxuICAgICAgICAvKiBTQUZFVFk6IEFQSSDrjbDsvZTroIjsnbTthLDsmYAgWm9kIOqygOymneq4sCDrk7HroZ0g6rOE7JW97J20IOydtCDqsJLsnZgg7YOA7J6F7J2EIOuztOyepe2VnOuLpC4gKi8gKFxuICAgICAgICAgIHJlcXVlc3QucGFyYW1zIGFzIHsgZmlsZW5hbWU6IHN0cmluZyB9XG4gICAgICAgICkuZmlsZW5hbWU7XG4gICAgICBjb25zdCBhc3NldHNEaXIgPSBwYXRoLmpvaW4od2ViRGlzdFBhdGgsIFwiYXNzZXRzXCIpO1xuICAgICAgY29uc3Qgc2FmZUZpbGVQYXRoID0gdGhpcy5yZXNvbHZlUGF0aFdpdGhpbkJhc2VEaXIoYXNzZXRzRGlyLCByZXF1ZXN0ZWRGaWxlKTtcbiAgICAgIGlmIChzYWZlRmlsZVBhdGggPT09IG51bGwpIHtcbiAgICAgICAgcmVwbHkuc3RhdHVzKDQwMykuc2VuZCgpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBjb25zdCBub3JtYWxpemVkUmVxdWVzdGVkRmlsZSA9IHBhdGgucmVsYXRpdmUoYXNzZXRzRGlyLCBzYWZlRmlsZVBhdGgpLnJlcGxhY2UoL1xcXFwvZywgXCIvXCIpO1xuXG4gICAgICBjb25zdCBhc3NldFBhdGggPSBgL2Fzc2V0cy8ke25vcm1hbGl6ZWRSZXF1ZXN0ZWRGaWxlfWA7XG5cbiAgICAgIC8vIENhY2hlLUNvbnRyb2wg7Zek642UIOqysOyglVxuICAgICAgY29uc3QgZ2V0Q2FjaGVDb250cm9sRm9yQXNzZXQgPSAoKTogQ2FjaGVDb250cm9sQ29uZmlnID0+IHtcbiAgICAgICAgY29uc3QgY2FjaGVSZXE6IENhY2hlQ29udHJvbFJlcXVlc3QgPSB7XG4gICAgICAgICAgdHlwZTogXCJhc3NldHNcIixcbiAgICAgICAgICB1cmw6IHJlcXVlc3QudXJsLFxuICAgICAgICAgIHBhdGg6IGFzc2V0UGF0aCxcbiAgICAgICAgICBtZXRob2Q6IHJlcXVlc3QubWV0aG9kLFxuICAgICAgICB9O1xuXG4gICAgICAgIC8vIOyCrOyaqeyekCDsoJXsnZgg7ZW465Ok65+sIOyasOyEoFxuICAgICAgICBpZiAoY29uZmlnLmNhY2hlQ29udHJvbEhhbmRsZXIpIHtcbiAgICAgICAgICBjb25zdCByZXN1bHQgPSBjb25maWcuY2FjaGVDb250cm9sSGFuZGxlcihjYWNoZVJlcSk7XG4gICAgICAgICAgaWYgKHJlc3VsdCkgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIOq4sOuzuOqwkjogaW1tdXRhYmxlXG4gICAgICAgIHJldHVybiBDYWNoZVByZXNldHMuaW1tdXRhYmxlO1xuICAgICAgfTtcblxuICAgICAgLy8gaW5kZXgtKi5qcyDrmJDripQgaW5kZXgtKi5jc3Mg7JqU7LKt7J24IOqyveyasFxuICAgICAgaWYgKC9eaW5kZXgtW2EtZjAtOV0rXFwuKGpzfGNzcykkLy50ZXN0KG5vcm1hbGl6ZWRSZXF1ZXN0ZWRGaWxlKSkge1xuICAgICAgICBjb25zdCBleHQgPSBub3JtYWxpemVkUmVxdWVzdGVkRmlsZS5zcGxpdChcIi5cIikucG9wKCk7XG4gICAgICAgIGNvbnN0IGZpbGVzID0gYXdhaXQgZnMucmVhZGRpcihhc3NldHNEaXIpO1xuICAgICAgICBjb25zdCBjdXJyZW50RmlsZSA9IGZpbGVzLmZpbmQoKGYpID0+IGYuc3RhcnRzV2l0aChcImluZGV4LVwiKSAmJiBmLmVuZHNXaXRoKGAuJHtleHR9YCkpO1xuXG4gICAgICAgIGlmIChjdXJyZW50RmlsZSkge1xuICAgICAgICAgIGNvbnN0IGZpbGVQYXRoID0gcGF0aC5qb2luKGFzc2V0c0RpciwgY3VycmVudEZpbGUpO1xuICAgICAgICAgIGNvbnN0IGNvbnRlbnQgPSBhd2FpdCBmcy5yZWFkRmlsZShmaWxlUGF0aCk7XG4gICAgICAgICAgcmVwbHkudHlwZShleHQgPT09IFwianNcIiA/IFwiYXBwbGljYXRpb24vamF2YXNjcmlwdFwiIDogXCJ0ZXh0L2Nzc1wiKTtcbiAgICAgICAgICBhcHBseUNhY2hlSGVhZGVycyhyZXBseSwgZ2V0Q2FjaGVDb250cm9sRm9yQXNzZXQoKSk7XG4gICAgICAgICAgcmV0dXJuIHJlcGx5LnNlbmQoY29udGVudCk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8g7J2867CYIO2MjOydvCDshJzruZlcbiAgICAgIGNvbnN0IGZpbGVQYXRoID0gc2FmZUZpbGVQYXRoO1xuICAgICAgaWYgKGF3YWl0IGV4aXN0cyhmaWxlUGF0aCkpIHtcbiAgICAgICAgY29uc3QgY29udGVudCA9IGF3YWl0IGZzLnJlYWRGaWxlKGZpbGVQYXRoKTtcbiAgICAgICAgY29uc3QgZXh0ID0gbm9ybWFsaXplZFJlcXVlc3RlZEZpbGUuc3BsaXQoXCIuXCIpLnBvcCgpO1xuICAgICAgICByZXBseS50eXBlKGV4dCA9PT0gXCJqc1wiID8gXCJhcHBsaWNhdGlvbi9qYXZhc2NyaXB0XCIgOiBleHQgPT09IFwiY3NzXCIgPyBcInRleHQvY3NzXCIgOiBcIlwiKTtcbiAgICAgICAgaWYgKG5vcm1hbGl6ZWRSZXF1ZXN0ZWRGaWxlLmluY2x1ZGVzKFwiLVwiKSkge1xuICAgICAgICAgIGFwcGx5Q2FjaGVIZWFkZXJzKHJlcGx5LCBnZXRDYWNoZUNvbnRyb2xGb3JBc3NldCgpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVwbHkuc2VuZChjb250ZW50KTtcbiAgICAgIH1cblxuICAgICAgcmVwbHkuc3RhdHVzKDQwNCkuc2VuZCgpO1xuICAgIH0pO1xuXG4gICAgLy8gU1NSIOudvOyasO2KuCDqsJzrs4Qg65Ox66GdIChjb21wcmVzcyDsmLXshZjsnbQg65287Jqw7Yq467OE66GcIOyggeyaqeuQmOuPhOuhnSlcbiAgICBpZiAoc3NyQXZhaWxhYmxlKSB7XG4gICAgICBjb25zdCB7IGdldFNTUlJvdXRlcyB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vc3NyXCIpO1xuICAgICAgY29uc3QgeyByZW5kZXJTU1IgfSA9IGF3YWl0IGltcG9ydChcIi4uL3Nzci9yZW5kZXJlclwiKTtcbiAgICAgIGNvbnN0IHNzclJvdXRlcyA9IGdldFNTUlJvdXRlcygpO1xuXG4gICAgICBmb3IgKGNvbnN0IHJvdXRlIG9mIHNzclJvdXRlcykge1xuICAgICAgICBzZXJ2ZXIucm91dGUoe1xuICAgICAgICAgIG1ldGhvZDogW1wiR0VUXCIsIFwiSEVBRFwiXSxcbiAgICAgICAgICB1cmw6IHJvdXRlLnBhdGgsXG4gICAgICAgICAgY29tcHJlc3M6IHRvRmFzdGlmeUNvbXByZXNzT3B0aW9uKHJvdXRlLmNvbXByZXNzID8/IHRydWUsIGdsb2JhbENvbXByZXNzT3B0aW9ucyksXG4gICAgICAgICAgaGFuZGxlcjogYXN5bmMgKHJlcXVlc3QsIHJlcGx5KSA9PiB7XG4gICAgICAgICAgICBjb25zdCB1cmwgPSByZXF1ZXN0LnVybDtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKGBbU1NSXSBNYXRjaGVkIHJvdXRlOiAke3JvdXRlLnBhdGh9YCk7XG5cbiAgICAgICAgICAgIGNvbnN0IHBhcmFtcyA9IHRoaXMuZXh0cmFjdFBhdGhQYXJhbXMocm91dGUucGF0aCwgdXJsKTtcbiAgICAgICAgICAgIGNvbnN0IGh0bWwgPSBhd2FpdCByZW5kZXJTU1IodXJsLCByb3V0ZSwgcGFyYW1zLCByZXF1ZXN0LCByZXBseSwgY29uZmlnKTtcblxuICAgICAgICAgICAgcmVwbHkudHlwZShcInRleHQvaHRtbFwiKTtcbiAgICAgICAgICAgIHJldHVybiBodG1sO1xuICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIENTUiBvciBTdGF0aWMgRmlsZSBGYWxsYmFjayAoU1NSIOudvOyasO2KuOyXkCDrp6Tsua3rkJjsp4Ag7JWK64qUIOuqqOuToCDsmpTssq0pXG4gICAgc2VydmVyLnJvdXRlKHtcbiAgICAgIG1ldGhvZDogW1wiR0VUXCIsIFwiSEVBRFwiXSxcbiAgICAgIHVybDogXCIqXCIsXG4gICAgICBoYW5kbGVyOiBhc3luYyAocmVxdWVzdCwgcmVwbHkpID0+IHtcbiAgICAgICAgLy8gL2FwaSwgL3NvbmFtdS11aeuKlCA0MDQg6re464yA66GcXG4gICAgICAgIGlmIChyZXF1ZXN0LnVybC5zdGFydHNXaXRoKFwiL2FwaVwiKSB8fCByZXF1ZXN0LnVybC5zdGFydHNXaXRoKFwiL3NvbmFtdS11aVwiKSkge1xuICAgICAgICAgIHJlcGx5LnN0YXR1cyg0MDQpLnNlbmQoKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICAvLyBDU1LsmqkgQ2FjaGUtQ29udHJvbCDtl6TrjZQg7ISk7KCVXG4gICAgICAgIGlmIChjb25maWcuY2FjaGVDb250cm9sSGFuZGxlcikge1xuICAgICAgICAgIGNvbnN0IGNzckNhY2hlUmVxOiBDYWNoZUNvbnRyb2xSZXF1ZXN0ID0ge1xuICAgICAgICAgICAgdHlwZTogXCJjc3JcIixcbiAgICAgICAgICAgIHVybDogcmVxdWVzdC51cmwsXG4gICAgICAgICAgICBwYXRoOiByZXF1ZXN0LnVybC5zcGxpdChcIj9cIilbMF0sXG4gICAgICAgICAgICBtZXRob2Q6IHJlcXVlc3QubWV0aG9kLFxuICAgICAgICAgIH07XG4gICAgICAgICAgY29uc3QgY3NyQ2FjaGVDb25maWcgPSBjb25maWcuY2FjaGVDb250cm9sSGFuZGxlcihjc3JDYWNoZVJlcSk7XG5cbiAgICAgICAgICBpZiAoY3NyQ2FjaGVDb25maWcpIHtcbiAgICAgICAgICAgIGFwcGx5Q2FjaGVIZWFkZXJzKHJlcGx5LCBjc3JDYWNoZUNvbmZpZyk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8g7KCV7KCBIO2MjOydvOydtCDsobTsnqztlaAg6rK97JqwLCDsoJXsoIEg7YyM7J287J2EIOuovOyggCDshJzruZntlbTslbztlahcbiAgICAgICAgY29uc3QgcmVxdWVzdFBhdGggPSB0aGlzLmdldFBhdGhuYW1lRnJvbVVybChyZXF1ZXN0LnVybCk7XG4gICAgICAgIGNvbnN0IHNhZmVGaWxlUGF0aCA9IHRoaXMucmVzb2x2ZVBhdGhXaXRoaW5CYXNlRGlyKHdlYkRpc3RQYXRoLCByZXF1ZXN0UGF0aCk7XG4gICAgICAgIGlmIChzYWZlRmlsZVBhdGggPT09IG51bGwpIHtcbiAgICAgICAgICByZXBseS5zdGF0dXMoNDAzKS5zZW5kKCk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmIChhd2FpdCBmaWxlRXhpc3RzKHNhZmVGaWxlUGF0aCkpIHtcbiAgICAgICAgICBjb25zdCBjb250ZW50ID0gYXdhaXQgZnMucmVhZEZpbGUoc2FmZUZpbGVQYXRoKTtcbiAgICAgICAgICByZXR1cm4gcmVwbHkudHlwZShtaW1lTG9va3VwKHNhZmVGaWxlUGF0aCkgfHwgXCJhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW1cIikuc2VuZChjb250ZW50KTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIENTUiBmYWxsYmFjazogaW5kZXguaHRtbCDshJzruZlcbiAgICAgICAgY29uc3QgaW5kZXhQYXRoID0gcGF0aC5qb2luKHdlYkRpc3RQYXRoLCBcImluZGV4Lmh0bWxcIik7XG4gICAgICAgIHJldHVybiByZXBseS50eXBlKFwidGV4dC9odG1sXCIpLnNlbmQoYXdhaXQgZnMucmVhZEZpbGUoaW5kZXhQYXRoLCBcInV0Zi04XCIpKTtcbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICBjb25zb2xlLmxvZyhg4pyTIFN0YXRpYyB3ZWIgc2VydmVyIGNvbmZpZ3VyZWQgd2l0aCAke3NzckF2YWlsYWJsZSA/IFwiU1NSXCIgOiBcIkNTUiBvbmx5XCJ9IHN1cHBvcnRgKTtcbiAgfVxuXG4gIGNyZWF0ZUFwaUhhbmRsZXIoXG4gICAgYXBpOiBFeHRlbmRlZEFwaSxcbiAgICBjb25maWc6IFNvbmFtdUZhc3RpZnlDb25maWcsXG4gICAgbW9kZWxzOiBMb2FkZWRNb2RlbHMgPSB0aGlzLnN5bmNlci5tb2RlbHMsXG4gICAgZGVwZW5kZW5jaWVzOiBTb25hbXVIdHRwVmFsaWRhdG9yRGVwZW5kZW5jaWVzID0gZGVmYXVsdFNvbmFtdUh0dHBWYWxpZGF0b3JEZXBlbmRlbmNpZXMsXG4gICk6IChyZXF1ZXN0OiBGYXN0aWZ5UmVxdWVzdCwgcmVwbHk6IEZhc3RpZnlSZXBseSkgPT4gUHJvbWlzZTxBcGlNZXRob2RSZXN1bHQ+IHtcbiAgICBjb25zdCBwcmVwYXJlZFZhbGlkYXRvciA9IHRoaXMuZ2V0T3JDcmVhdGVIdHRwVmFsaWRhdG9yKGFwaSwgZGVwZW5kZW5jaWVzKTtcblxuICAgIHJldHVybiBhc3luYyAocmVxdWVzdDogRmFzdGlmeVJlcXVlc3QsIHJlcGx5OiBGYXN0aWZ5UmVwbHkpOiBQcm9taXNlPEFwaU1ldGhvZFJlc3VsdD4gPT4ge1xuICAgICAgY29uc3QgdmFsaWRhdG9yID1cbiAgICAgICAgcHJlcGFyZWRWYWxpZGF0b3IgaW5zdGFuY2VvZiBQcm9taXNlID8gYXdhaXQgcHJlcGFyZWRWYWxpZGF0b3IgOiBwcmVwYXJlZFZhbGlkYXRvcjtcbiAgICAgIC8vIENvbnRleHQg7IOd7ISxXG4gICAgICBjb25zdCBjb250ZXh0OiBDb250ZXh0ID0gYXdhaXQgdGhpcy5jcmVhdGVDb250ZXh0KGNvbmZpZywgcmVxdWVzdCwgcmVwbHkpO1xuXG4gICAgICByZXR1cm4gdGhpcy5hc3luY0xvY2FsU3RvcmFnZS5ydW4oeyBjb250ZXh0IH0sIGFzeW5jICgpID0+IHtcbiAgICAgICAgLy8gZ3VhcmRzIOyymOumrFxuICAgICAgICBydW5HdWFyZHMoe1xuICAgICAgICAgIGd1YXJkczogYXBpLm9wdGlvbnMuZ3VhcmRzLFxuICAgICAgICAgIGNvbmZpZyxcbiAgICAgICAgICByZXF1ZXN0LFxuICAgICAgICAgIGFwaSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gcmVxdWVzdCDtjIzsi7FcbiAgICAgICAgY29uc3Qgd2hpY2ggPSBhcGkub3B0aW9ucy5odHRwTWV0aG9kID09PSBcIkdFVFwiID8gXCJxdWVyeVwiIDogXCJib2R5XCI7XG4gICAgICAgIGxldCByZXFCb2R5ID0gbmV3IE1hcDxzdHJpbmcsIEFwaUFyZ3VtZW50PigpO1xuICAgICAgICAvLyDtjIzsnbwg7JeF66Gc65OcIOyeiOuKlCDqsr3smrAg7J6E7IucIOuNsOydtO2EsFxuICAgICAgICBjb25zdCBmaWxlczogVXBsb2FkZWRSZXF1ZXN0RmlsZXMgPSB7XG4gICAgICAgICAgYnVmZmVyZWRGaWxlczogW10sXG4gICAgICAgICAgdXBsb2FkZWRGaWxlczogW10sXG4gICAgICAgIH07XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjb25zdCBib2R5ID0gcmVxdWVzdFt3aGljaF0gPz8ge307XG4gICAgICAgICAgaWYgKGFwaS51cGxvYWRPcHRpb25zKSB7XG4gICAgICAgICAgICBjb25zdCBwYXJ0cyA9IHJlcXVlc3QucGFydHMoe1xuICAgICAgICAgICAgICBsaW1pdHM6IGFwaS51cGxvYWRPcHRpb25zLmxpbWl0cyxcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAvLyBGb3JtRGF0YeydmCBmaWVsZOuTpOydhCDsnoTsi5zroZwg7KCA7J6lXG4gICAgICAgICAgICBjb25zdCBmaWVsZHM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7fTtcblxuICAgICAgICAgICAgaWYgKGFwaS51cGxvYWRPcHRpb25zLmNvbnN1bWUgPT09IFwiYnVmZmVyXCIgfHwgIWFwaS51cGxvYWRPcHRpb25zLmNvbnN1bWUpIHtcbiAgICAgICAgICAgICAgLy8gQnVmZmVyIOuqqOuTnDog66mU66qo66as7JeQIOuhnOuTnFxuICAgICAgICAgICAgICBmb3IgYXdhaXQgKGNvbnN0IHBhcnQgb2YgcGFydHMpIHtcbiAgICAgICAgICAgICAgICBpZiAocGFydC50eXBlID09PSBcImZpbGVcIikge1xuICAgICAgICAgICAgICAgICAgLy8gQ1JJVElDQUw6IO2MjOydvCDsiqTtirjrprzsnYQg7KaJ7IucIGNvbnN1bWXtlbTslbwg64uk7J2MIHBhcnTroZwg64SY7Ja06rCIIOyImCDsnojsnYxcbiAgICAgICAgICAgICAgICAgIC8vIOydtCDtmLjstpzsnbQg7JeG7Jy866m0IOyiheyihSBtdWx0aXBhcnQg7YyM7Iux7J20IHBlbmRpbmcg7IOB7YOc66GcIO2DgOyehOyVhOybgyDrsJzsg51cbiAgICAgICAgICAgICAgICAgIGNvbnN0IGJ1ZmZlciA9IGF3YWl0IHBhcnQudG9CdWZmZXIoKTtcbiAgICAgICAgICAgICAgICAgIGZpbGVzLmJ1ZmZlcmVkRmlsZXMucHVzaChuZXcgQnVmZmVyZWRGaWxlKHBhcnQsIGJ1ZmZlcikpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocGFydC50eXBlID09PSBcImZpZWxkXCIpIHtcbiAgICAgICAgICAgICAgICAgIGZpZWxkc1twYXJ0LmZpZWxkbmFtZV0gPSBTdHJpbmcocGFydC52YWx1ZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGFwaS51cGxvYWRPcHRpb25zLmNvbnN1bWUgPT09IFwic3RyZWFtXCIpIHtcbiAgICAgICAgICAgICAgLy8gU3RyZWFtIOuqqOuTnDog7KaJ7IucIOyggOyepeyGjOuhnCDsiqTtirjrpqzrsI1cbiAgICAgICAgICAgICAgY29uc3QgZGlza05hbWUgPSBhcGkudXBsb2FkT3B0aW9ucy5kZXN0aW5hdGlvbjtcbiAgICAgICAgICAgICAgY29uc3QgZGlzayA9IHRoaXMuc3RvcmFnZS51c2UoZGlza05hbWUpO1xuXG4gICAgICAgICAgICAgIC8vIOyasOyEoOyInOychDog642w7L2U66CI7J207YSwID4g7KCE7JetIOyEpOyglSA+IOq4sOuzuOqwklxuICAgICAgICAgICAgICBjb25zdCBrZXlHZW5lcmF0b3I6IEtleUdlbmVyYXRvciA9XG4gICAgICAgICAgICAgICAgYXBpLnVwbG9hZE9wdGlvbnMua2V5R2VuZXJhdG9yID8/XG4gICAgICAgICAgICAgICAgdGhpcy5jb25maWcuc2VydmVyLnN0b3JhZ2U/LmtleUdlbmVyYXRvciA/P1xuICAgICAgICAgICAgICAgIGRlZmF1bHRLZXlHZW5lcmF0b3I7XG5cbiAgICAgICAgICAgICAgZm9yIGF3YWl0IChjb25zdCBwYXJ0IG9mIHBhcnRzKSB7XG4gICAgICAgICAgICAgICAgaWYgKHBhcnQudHlwZSA9PT0gXCJmaWxlXCIpIHtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IGtleSA9IGF3YWl0IGtleUdlbmVyYXRvcih7XG4gICAgICAgICAgICAgICAgICAgIGZpbGVuYW1lOiBwYXJ0LmZpbGVuYW1lLFxuICAgICAgICAgICAgICAgICAgICBtaW1ldHlwZTogcGFydC5taW1ldHlwZSxcbiAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgICBhd2FpdCBkaXNrLnB1dFN0cmVhbShrZXksIHBhcnQuZmlsZSwge1xuICAgICAgICAgICAgICAgICAgICBjb250ZW50VHlwZTogcGFydC5taW1ldHlwZSxcbiAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgICBjb25zdCB1cmwgPSBhd2FpdCBkaXNrLmdldFVybChrZXkpO1xuICAgICAgICAgICAgICAgICAgY29uc3Qgc2lnbmVkVXJsID0gYXdhaXQgZGlzay5nZXRTaWduZWRVcmwoa2V5KTtcblxuICAgICAgICAgICAgICAgICAgZmlsZXMudXBsb2FkZWRGaWxlcy5wdXNoKFxuICAgICAgICAgICAgICAgICAgICBuZXcgVXBsb2FkZWRGaWxlKHtcbiAgICAgICAgICAgICAgICAgICAgICBmaWxlbmFtZTogcGFydC5maWxlbmFtZSxcbiAgICAgICAgICAgICAgICAgICAgICBtaW1ldHlwZTogcGFydC5taW1ldHlwZSxcbiAgICAgICAgICAgICAgICAgICAgICBzaXplOiBwYXJ0LmZpbGUuYnl0ZXNSZWFkLFxuICAgICAgICAgICAgICAgICAgICAgIHVybCxcbiAgICAgICAgICAgICAgICAgICAgICBzaWduZWRVcmwsXG4gICAgICAgICAgICAgICAgICAgICAga2V5LFxuICAgICAgICAgICAgICAgICAgICAgIGRpc2tOYW1lLFxuICAgICAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChwYXJ0LnR5cGUgPT09IFwiZmllbGRcIikge1xuICAgICAgICAgICAgICAgICAgZmllbGRzW3BhcnQuZmllbGRuYW1lXSA9IFN0cmluZyhwYXJ0LnZhbHVlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gcXProZwg7KSR7LKpIOq1rOyhsCDtjIzsi7E6IHBhcmFtc1tjYXRlZ29yeV0g4oaSIHsgcGFyYW1zOiB7IGNhdGVnb3J5OiBcInRlc3RcIiB9IH1cbiAgICAgICAgICAgIGNvbnN0IHFzID0gYXdhaXQgaW1wb3J0KFwicXNcIik7XG4gICAgICAgICAgICBjb25zdCBwYXJzZWQgPSBxcy5kZWZhdWx0LnBhcnNlKGZpZWxkcyk7XG4gICAgICAgICAgICBPYmplY3QuYXNzaWduKGJvZHksIHBhcnNlZCk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmVxQm9keSA9IHRvQXBpQXJndW1lbnRNYXAodmFsaWRhdG9yLnBhcnNlKGJvZHkpKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgIGNvbnN0IHsgWm9kRXJyb3IgfSA9IGF3YWl0IGltcG9ydChcInpvZFwiKTtcbiAgICAgICAgICBpZiAoZSBpbnN0YW5jZW9mIFpvZEVycm9yKSB7XG4gICAgICAgICAgICBjb25zdCB7IGh1bWFuaXplWm9kRXJyb3IgfSA9IGF3YWl0IGltcG9ydChcIi4uL3V0aWxzL3pvZC1lcnJvclwiKTtcbiAgICAgICAgICAgIGNvbnN0IG1lc3NhZ2VzID0gaHVtYW5pemVab2RFcnJvcihlKVxuICAgICAgICAgICAgICAubWFwKChpc3N1ZSkgPT4gaXNzdWUubWVzc2FnZSlcbiAgICAgICAgICAgICAgLmpvaW4oXCIgXCIpO1xuICAgICAgICAgICAgY29uc3QgeyBCYWRSZXF1ZXN0RXhjZXB0aW9uIH0gPSBhd2FpdCBpbXBvcnQoXCIuLi9leGNlcHRpb25zL3NvLWV4Y2VwdGlvbnNcIik7XG4gICAgICAgICAgICB0aHJvdyBuZXcgQmFkUmVxdWVzdEV4Y2VwdGlvbihcbiAgICAgICAgICAgICAgLyogU0FGRVRZOiBBUEkg642w7L2U66CI7J207YSw7JmAIFpvZCDqsoDspp3quLAg65Ox66GdIOqzhOyVveydtCDsnbQg6rCS7J2YIO2DgOyeheydhCDrs7TsnqXtlZzri6QuICovIG1lc3NhZ2VzIGFzIExvY2FsaXplZFN0cmluZyxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHpvZEVycm9yOiBlLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhyb3cgZTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBDb250ZW50LVR5cGVcbiAgICAgICAgcmVwbHkudHlwZShhcGkub3B0aW9ucy5jb250ZW50VHlwZSA/PyBcImFwcGxpY2F0aW9uL2pzb25cIik7XG5cbiAgICAgICAgLy8gQ2FjaGUtQ29udHJvbCDtl6TrjZQg7ISk7KCVXG4gICAgICAgIGNvbnN0IGFwaUNhY2hlQ29uZmlnID0gdGhpcy5nZXRBcGlDYWNoZUNvbnRyb2woYXBpLCByZXF1ZXN0LCBjb25maWcpO1xuICAgICAgICBpZiAoYXBpQ2FjaGVDb25maWcpIHtcbiAgICAgICAgICBhcHBseUNhY2hlSGVhZGVycyhyZXBseSwgYXBpQ2FjaGVDb25maWcpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8g7JeF66Gc65OcIOyYteyFmOydtCDsnojripQg6rK97JqwIO2MjOydvCDrjbDsnbTthLDrpbwgQ29udGV4dOyXkCDstpTqsIBcbiAgICAgICAgaWYgKGFwaS51cGxvYWRPcHRpb25zKSB7XG4gICAgICAgICAgY29uc3QgY29uc3VtZSA9IGFwaS51cGxvYWRPcHRpb25zLmNvbnN1bWUgPz8gXCJidWZmZXJcIjtcbiAgICAgICAgICBpZiAoY29uc3VtZSA9PT0gXCJidWZmZXJcIikge1xuICAgICAgICAgICAgY29udGV4dC5idWZmZXJlZEZpbGVzID0gZmlsZXMuYnVmZmVyZWRGaWxlcztcbiAgICAgICAgICB9IGVsc2UgaWYgKGNvbnN1bWUgPT09IFwic3RyZWFtXCIpIHtcbiAgICAgICAgICAgIGNvbnRleHQudXBsb2FkZWRGaWxlcyA9IGZpbGVzLnVwbG9hZGVkRmlsZXM7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8g66qo6424IOuplOyGjOuTnCBhcmdzIOyDneyEse2VmOyXrCDtmLjstpxcbiAgICAgICAgY29uc3QgeyBBcGlQYXJhbVR5cGUgfSA9IGF3YWl0IGltcG9ydChcIi4uL3R5cGVzL3R5cGVzXCIpO1xuICAgICAgICBjb25zdCBhcmdzID0gYXBpLnBhcmFtZXRlcnMubWFwKChwYXJhbSkgPT4ge1xuICAgICAgICAgIC8vIENvbnRleHQg7J247KCd7IWYXG4gICAgICAgICAgaWYgKEFwaVBhcmFtVHlwZS5pc0NvbnRleHQocGFyYW0udHlwZSkpIHtcbiAgICAgICAgICAgIHJldHVybiBjb250ZXh0O1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gcmVxQm9keS5nZXQocGFyYW0ubmFtZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4gdGhpcy5pbnZva2VNb2RlbE1ldGhvZChhcGksIGFyZ3MsIHJlcGx5LCBtb2RlbHMpO1xuICAgICAgfSk7XG4gICAgfTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0T3JDcmVhdGVIdHRwVmFsaWRhdG9yKFxuICAgIGFwaTogRXh0ZW5kZWRBcGksXG4gICAgZGVwZW5kZW5jaWVzOiBTb25hbXVIdHRwVmFsaWRhdG9yRGVwZW5kZW5jaWVzLFxuICApOiBIdHRwVmFsaWRhdG9yIHwgUHJvbWlzZTxIdHRwVmFsaWRhdG9yPiB7XG4gICAgY29uc3QgY2FjaGVkID0gdGhpcy5odHRwVmFsaWRhdG9ycy5nZXQoYXBpKTtcbiAgICBpZiAoY2FjaGVkICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiBjYWNoZWQ7XG4gICAgfVxuICAgIGNvbnN0IGV4aXN0aW5nID0gdGhpcy5wZW5kaW5nSHR0cFZhbGlkYXRvcnMuZ2V0KGFwaSk7XG4gICAgaWYgKGV4aXN0aW5nICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiBleGlzdGluZztcbiAgICB9XG4gICAgY29uc3QgcGVuZGluZyA9IHRoaXMuYnVpbGRIdHRwVmFsaWRhdG9yKGFwaSwgZGVwZW5kZW5jaWVzKTtcbiAgICB0aGlzLnBlbmRpbmdIdHRwVmFsaWRhdG9ycy5zZXQoYXBpLCBwZW5kaW5nKTtcbiAgICB2b2lkIHBlbmRpbmcudGhlbihcbiAgICAgICh2YWxpZGF0b3IpID0+IHtcbiAgICAgICAgdGhpcy5odHRwVmFsaWRhdG9ycy5zZXQoYXBpLCB2YWxpZGF0b3IpO1xuICAgICAgICB0aGlzLnBlbmRpbmdIdHRwVmFsaWRhdG9ycy5kZWxldGUoYXBpKTtcbiAgICAgIH0sXG4gICAgICAoKSA9PiB7XG4gICAgICAgIHRoaXMucGVuZGluZ0h0dHBWYWxpZGF0b3JzLmRlbGV0ZShhcGkpO1xuICAgICAgfSxcbiAgICApO1xuICAgIHJldHVybiBwZW5kaW5nO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBidWlsZEh0dHBWYWxpZGF0b3IoXG4gICAgYXBpOiBFeHRlbmRlZEFwaSxcbiAgICBkZXBlbmRlbmNpZXM6IFNvbmFtdUh0dHBWYWxpZGF0b3JEZXBlbmRlbmNpZXMsXG4gICk6IFByb21pc2U8SHR0cFZhbGlkYXRvcj4ge1xuICAgIGNvbnN0IHBvbGljeSA9IG5vcm1hbGl6ZVpvZENvbXBpbGVyUG9saWN5KHRoaXMuY29uZmlnLnZhbGlkYXRpb24/LnpvZENvbXBpbGVyKTtcbiAgICBjb25zdCBzb3VyY2VBb3QgPSBwcm9jZXNzLmVudi5IT1QgPT09IFwieWVzXCIgfHwgcHJvY2Vzcy5lbnYuVklURVNUID09PSBcInRydWVcIjtcbiAgICBpZiAocG9saWN5LmFwaSA9PT0gXCJhb3RcIiAmJiAhc291cmNlQW90KSB7XG4gICAgICBjb25zdCByZWdpc3RyeSA9IHRoaXMuYW90SHR0cFZhbGlkYXRvclJlZ2lzdHJ5ID8/IChhd2FpdCB0aGlzLmxvYWRBb3RIdHRwVmFsaWRhdG9yUmVnaXN0cnkoKSk7XG4gICAgICByZXR1cm4gdGhpcy5nZXRBb3RIdHRwVmFsaWRhdG9yKGFwaSwgcmVnaXN0cnkpO1xuICAgIH1cblxuICAgIHJldHVybiBhd2FpdCBkZXBlbmRlbmNpZXMuY3JlYXRlVmFsaWRhdG9yKHtcbiAgICAgIGFwaSxcbiAgICAgIHBvbGljeSxcbiAgICAgIHR5cGVzOiB0aGlzLnN5bmNlci50eXBlcyxcbiAgICAgIGFsbG93QW90U291cmNlRmFsbGJhY2s6IHNvdXJjZUFvdCxcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0QW90SHR0cFZhbGlkYXRvcihhcGk6IEV4dGVuZGVkQXBpLCByZWdpc3RyeTogSHR0cFZhbGlkYXRvclJlZ2lzdHJ5KTogSHR0cFZhbGlkYXRvciB7XG4gICAgY29uc3Qgcm91dGVLZXkgPSBnZXRIdHRwVmFsaWRhdG9yUm91dGVLZXkoYXBpKTtcbiAgICBjb25zdCB2YWxpZGF0b3IgPSByZWdpc3RyeS52YWxpZGF0b3JzLmdldChyb3V0ZUtleSk7XG4gICAgaWYgKHZhbGlkYXRvciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEhUVFAgdmFsaWRhdG9yIHJlZ2lzdHJ5IGlzIG1pc3NpbmcgJHtyb3V0ZUtleX1gKTtcbiAgICB9XG4gICAgcmV0dXJuIHZhbGlkYXRvcjtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgbG9hZEFvdEh0dHBWYWxpZGF0b3JSZWdpc3RyeShcbiAgICBhcGlzOiByZWFkb25seSBFeHRlbmRlZEFwaVtdID0gdGhpcy5zeW5jZXIuYXBpcyxcbiAgICBkZXBlbmRlbmNpZXM6IFNvbmFtdUh0dHBWYWxpZGF0b3JEZXBlbmRlbmNpZXMgPSBkZWZhdWx0U29uYW11SHR0cFZhbGlkYXRvckRlcGVuZGVuY2llcyxcbiAgKTogUHJvbWlzZTxIdHRwVmFsaWRhdG9yUmVnaXN0cnk+IHtcbiAgICBjb25zdCB7IHBhdGhUb0ZpbGVVUkwgfSA9IGF3YWl0IGltcG9ydChcIm5vZGU6dXJsXCIpO1xuICAgIGNvbnN0IHJlZ2lzdHJ5UGF0aCA9IHBhdGguam9pbihcbiAgICAgIHRoaXMuYXBpUm9vdFBhdGgsXG4gICAgICBcImRpc3QvYXBwbGljYXRpb24vc29uYW11LnZhbGlkYXRvcnMuZ2VuZXJhdGVkLmpzXCIsXG4gICAgKTtcbiAgICBpZiAoIShhd2FpdCBleGlzdHMocmVnaXN0cnlQYXRoKSkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgR2VuZXJhdGVkIEhUVFAgdmFsaWRhdG9yIHJlZ2lzdHJ5IG5vdCBmb3VuZDogJHtyZWdpc3RyeVBhdGh9YCk7XG4gICAgfVxuXG4gICAgY29uc3QgaW1wb3J0ZWQgPVxuICAgICAgLyogU0FGRVRZOiBBUEkg642w7L2U66CI7J207YSw7JmAIFpvZCDqsoDspp3quLAg65Ox66GdIOqzhOyVveydtCDsnbQg6rCS7J2YIO2DgOyeheydhCDrs7TsnqXtlZzri6QuICovIChhd2FpdCBpbXBvcnQoXG4gICAgICAgIHBhdGhUb0ZpbGVVUkwocmVnaXN0cnlQYXRoKS5ocmVmXG4gICAgICApKSBhcyB7XG4gICAgICAgIGZpbmdlcnByaW50PzogdW5rbm93bjtcbiAgICAgICAgdmFsaWRhdG9ycz86IHVua25vd247XG4gICAgICB9O1xuICAgIGlmICghaXNTdHJpbmdWYWx1ZShpbXBvcnRlZC5maW5nZXJwcmludCkgfHwgIShpbXBvcnRlZC52YWxpZGF0b3JzIGluc3RhbmNlb2YgTWFwKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIGdlbmVyYXRlZCBIVFRQIHZhbGlkYXRvciByZWdpc3RyeTogJHtyZWdpc3RyeVBhdGh9YCk7XG4gICAgfVxuICAgIGZvciAoY29uc3QgW2tleSwgdmFsaWRhdG9yXSBvZiBpbXBvcnRlZC52YWxpZGF0b3JzKSB7XG4gICAgICBpZiAoXG4gICAgICAgICFpc1N0cmluZ1ZhbHVlKGtleSkgfHxcbiAgICAgICAgIWlzT2JqZWN0VmFsdWUodmFsaWRhdG9yKSB8fFxuICAgICAgICB2YWxpZGF0b3IgPT09IG51bGwgfHxcbiAgICAgICAgIShcInBhcnNlXCIgaW4gdmFsaWRhdG9yKSB8fFxuICAgICAgICAhaXNGdW5jdGlvblZhbHVlKHZhbGlkYXRvci5wYXJzZSlcbiAgICAgICkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgSFRUUCB2YWxpZGF0b3IgcmVnaXN0cnkgZW50cnk6ICR7U3RyaW5nKGtleSl9YCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgcmVnaXN0cnk6IEh0dHBWYWxpZGF0b3JSZWdpc3RyeSA9IHtcbiAgICAgIGZpbmdlcnByaW50OiBpbXBvcnRlZC5maW5nZXJwcmludCxcbiAgICAgIHZhbGlkYXRvcnM6IGltcG9ydGVkLnZhbGlkYXRvcnMsXG4gICAgfTtcbiAgICBkZXBlbmRlbmNpZXMuYXNzZXJ0UmVnaXN0cnkoYXBpcywgcmVnaXN0cnkpO1xuICAgIHJldHVybiByZWdpc3RyeTtcbiAgfVxuXG4gIGFzeW5jIHJlZnJlc2hIdHRwVmFsaWRhdG9ycyhcbiAgICBkZXBlbmRlbmNpZXM6IFNvbmFtdUh0dHBWYWxpZGF0b3JEZXBlbmRlbmNpZXMgPSBkZWZhdWx0U29uYW11SHR0cFZhbGlkYXRvckRlcGVuZGVuY2llcyxcbiAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgcG9saWN5ID0gbm9ybWFsaXplWm9kQ29tcGlsZXJQb2xpY3kodGhpcy5jb25maWcudmFsaWRhdGlvbj8uem9kQ29tcGlsZXIpO1xuICAgIGNvbnN0IHNvdXJjZUFvdCA9IHByb2Nlc3MuZW52LkhPVCA9PT0gXCJ5ZXNcIiB8fCBwcm9jZXNzLmVudi5WSVRFU1QgPT09IFwidHJ1ZVwiO1xuICAgIGNvbnN0IG5leHRBcGlzID0gWy4uLnRoaXMuc3luY2VyLmFwaXNdO1xuICAgIGNvbnN0IG5leHRNb2RlbHMgPSB7IC4uLnRoaXMuc3luY2VyLm1vZGVscyB9O1xuICAgIGNvbnN0IHJlc3RBcGlzID0gbmV4dEFwaXMuZmlsdGVyKChhcGkpID0+IGFwaS53ZWJzb2NrZXRPcHRpb25zID09PSB1bmRlZmluZWQpO1xuICAgIGNvbnN0IG5leHQgPSBuZXcgV2Vha01hcDxFeHRlbmRlZEFwaSwgSHR0cFZhbGlkYXRvcj4oKTtcbiAgICBsZXQgbmV4dEFvdFJlZ2lzdHJ5OiBIdHRwVmFsaWRhdG9yUmVnaXN0cnkgfCB1bmRlZmluZWQ7XG5cbiAgICBpZiAocG9saWN5LmFwaSA9PT0gXCJhb3RcIiAmJiAhc291cmNlQW90KSB7XG4gICAgICBjb25zdCByZWdpc3RyeSA9IGF3YWl0IHRoaXMubG9hZEFvdEh0dHBWYWxpZGF0b3JSZWdpc3RyeShuZXh0QXBpcywgZGVwZW5kZW5jaWVzKTtcbiAgICAgIGZvciAoY29uc3QgYXBpIG9mIHJlc3RBcGlzKSB7XG4gICAgICAgIG5leHQuc2V0KGFwaSwgdGhpcy5nZXRBb3RIdHRwVmFsaWRhdG9yKGFwaSwgcmVnaXN0cnkpKTtcbiAgICAgIH1cbiAgICAgIG5leHRBb3RSZWdpc3RyeSA9IHJlZ2lzdHJ5O1xuICAgIH0gZWxzZSB7XG4gICAgICBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgICAgcmVzdEFwaXMubWFwKGFzeW5jIChhcGkpID0+IHtcbiAgICAgICAgICBjb25zdCB2YWxpZGF0b3IgPSBhd2FpdCB0aGlzLmJ1aWxkSHR0cFZhbGlkYXRvcihhcGksIGRlcGVuZGVuY2llcyk7XG4gICAgICAgICAgbmV4dC5zZXQoYXBpLCB2YWxpZGF0b3IpO1xuICAgICAgICB9KSxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgLy8gdmFsaWRhdG9y7JmAIOqwmeydgCByZXZpc2lvbuydmCBBUEkvbW9kZWwgc25hcHNob3TsnYQg7ZWo6ruYIOqzteqwnO2VtCBITVIg7KSR6rCEIOyDge2DnOulvCDsiKjquYHri4jri6QuXG4gICAgdGhpcy5odHRwVmFsaWRhdG9ycyA9IG5leHQ7XG4gICAgdGhpcy5wZW5kaW5nSHR0cFZhbGlkYXRvcnMgPSBuZXcgV2Vha01hcCgpO1xuICAgIHRoaXMuYW90SHR0cFZhbGlkYXRvclJlZ2lzdHJ5ID0gbmV4dEFvdFJlZ2lzdHJ5O1xuICAgIHRoaXMucHJlcGFyZWRBcGlzID0gbmV4dEFwaXM7XG4gICAgdGhpcy5wcmVwYXJlZE1vZGVscyA9IG5leHRNb2RlbHM7XG4gIH1cblxuICAvLyBXUyBwYXRo66W8IOydvOuwmCBIVFRQIEdFVOycvOuhnCDtmLjstpztlZwg6rK97JqwIDQyNiArIFVwZ3JhZGUg7Zek642U66GcIOuqheyLnOyggeycvOuhnCB3ZWJzb2NrZXQg7KCR7IaN7J2EIOycoOuPhO2VqFxuICBwcml2YXRlIGNyZWF0ZVdlYlNvY2tldFVwZ3JhZGVSZXF1aXJlZEhhbmRsZXIoKSB7XG4gICAgcmV0dXJuIGFzeW5jIChfcmVxdWVzdDogRmFzdGlmeVJlcXVlc3QsIHJlcGx5OiBGYXN0aWZ5UmVwbHkpOiBQcm9taXNlPHZvaWQ+ID0+IHtcbiAgICAgIHJlcGx5LmhlYWRlcihcImNvbm5lY3Rpb25cIiwgXCJVcGdyYWRlXCIpLmhlYWRlcihcInVwZ3JhZGVcIiwgXCJ3ZWJzb2NrZXRcIikuc3RhdHVzKDQyNikuc2VuZCh7XG4gICAgICAgIG1lc3NhZ2U6IFwiV2ViU29ja2V0IHVwZ3JhZGUgcmVxdWlyZWRcIixcbiAgICAgIH0pO1xuICAgIH07XG4gIH1cblxuICAvLyBkZXYg66qo65Oc7J2YIGNhdGNoLWFsbCB3c0hhbmRsZXLsl5DshJwg7Iuk7KCcIFdTIEFQSeuhnCDrlJTsiqTtjKjsuZjtlaguIOunpOy5reuQmOuKlCByb3V0ZeqwgCDsl4bsnLzrqbQgMTAwOOuhnCDri6vsnYxcbiAgcHJpdmF0ZSBhc3luYyBoYW5kbGVEZXZXZWJTb2NrZXRSZXF1ZXN0KFxuICAgIHNvY2tldDogV2ViU29ja2V0LFxuICAgIHJlcXVlc3Q6IEZhc3RpZnlSZXF1ZXN0LFxuICAgIGNvbmZpZzogU29uYW11RmFzdGlmeUNvbmZpZyxcbiAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgbWF0Y2hlZEFwaSA9IHRoaXMuZmluZE1hdGNoZWRBcGkocmVxdWVzdCwgdGhpcy5zeW5jZXIuYXBpcywgdGhpcy5zeW5jZXIubW9kZWxzKTtcbiAgICBpZiAoIW1hdGNoZWRBcGk/LndlYnNvY2tldE9wdGlvbnMpIHtcbiAgICAgIGNvbnN0IHRyYWNlQ29udGV4dCA9IHRoaXMud2Vic29ja2V0UnVudGltZS50ZWxlbWV0cnlDb250cm9sbGVyLmNyZWF0ZUNvbm5lY3Rpb25Db250ZXh0KHtcbiAgICAgICAgaGVhZGVyczogcmVxdWVzdC5oZWFkZXJzLFxuICAgICAgfSk7XG4gICAgICB0aGlzLndlYnNvY2tldFJ1bnRpbWUudGVsZW1ldHJ5Q29udHJvbGxlci5lbWl0KHtcbiAgICAgICAgbmFtZTogXCJ3cy5jb25uZWN0aW9uLnJlamVjdGVkXCIsXG4gICAgICAgIGxldmVsOiBcIndhcm5cIixcbiAgICAgICAgZGV0YWlsOiB7XG4gICAgICAgICAgcmVhc29uOiBcInJvdXRlTm90Rm91bmRcIixcbiAgICAgICAgICBwYXRoOiByZXF1ZXN0LnVybCxcbiAgICAgICAgfSxcbiAgICAgICAgdHJhY2VJZDogdHJhY2VDb250ZXh0LnRyYWNlSWQsXG4gICAgICAgIHNwYW5JZDogdHJhY2VDb250ZXh0LnNwYW5JZCxcbiAgICAgICAgcGFyZW50U3BhbklkOiB0cmFjZUNvbnRleHQucGFyZW50U3BhbklkLFxuICAgICAgICBzYW1wbGVkOiB0cmFjZUNvbnRleHQuc2FtcGxlZCxcbiAgICAgIH0pO1xuICAgICAgc29ja2V0LmNsb3NlKDEwMDgsIFwiV2ViU29ja2V0IHJvdXRlIG5vdCBmb3VuZFwiKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBoYW5kbGVyID0gdGhpcy5jcmVhdGVXZWJTb2NrZXRIYW5kbGVyKG1hdGNoZWRBcGksIGNvbmZpZyk7XG4gICAgYXdhaXQgaGFuZGxlcih7IHNvY2tldCB9LCByZXF1ZXN0KTtcbiAgfVxuXG4gIC8vIFdTIHJvdXRlIO2VuOuTpOufrOydmCDsi6Ttlokg7Iic7ISc66W8IOqzoOygle2VqDpcbiAgLy8gMSkgcXVlcnkgcGFyYW0g7YyM7Iux7J2EIGFjdGl2YXRpb24g7KCE7JeQIOuBneuCtCBoYW5kc2hha2Ug7Iuk7Yyo6rCAIHJlZ2lzdHJ57JeQIOuFuOy2nOuQmOyngCDslYrqsowg7ZWoXG4gIC8vIDIpIGBhY3RpdmU6IGZhbHNlYOuhnCDrqLzsoIAg65Ox66Gd7ZWcIOuSpCBjb250ZXh0IOyViOyXkOyEnCBndWFyZOulvCDsi6TtlontlbQg7J247KadIOygleuztOulvCDssLjsobDtlaAg7IiYIOyeiOqyjCDtlahcbiAgLy8gMykgY29udGV4dC9ndWFyZCDspIDruYTqsIAg64Gd64KcIOuSpCBgYWN0aXZhdGUoKWDtlbQg67iM66Gc65Oc7LqQ7Iqk7Yq46rCAIOy0iOq4sO2ZlCDspJHqsIQg7IOB7YOc66W8IOuztOyngCDrqrvtlZjqsowg7ZWoXG4gIC8vIOyXkOufrCDrsJzsg50g7Iuc7JeQ64qUIHJlc29sdmVXZWJTb2NrZXRDbG9zZURlc2NyaXB0b3Ig7KCV7LGF7JeQIOuUsOudvCBjbG9zZSBjb2Rl66W8IOunpO2Vke2VqFxuICBjcmVhdGVXZWJTb2NrZXRIYW5kbGVyRm9yVGVzdGluZyhhcGk6IEV4dGVuZGVkQXBpLCBjb25maWc6IFNvbmFtdUZhc3RpZnlDb25maWcpIHtcbiAgICByZXR1cm4gdGhpcy5jcmVhdGVXZWJTb2NrZXRIYW5kbGVyKGFwaSwgY29uZmlnKTtcbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlV2ViU29ja2V0SGFuZGxlcihhcGk6IEV4dGVuZGVkQXBpLCBjb25maWc6IFNvbmFtdUZhc3RpZnlDb25maWcpIHtcbiAgICByZXR1cm4gYXN5bmMgKFxuICAgICAgY29ubmVjdGlvbjoge1xuICAgICAgICBzb2NrZXQ6IFdlYlNvY2tldDtcbiAgICAgIH0sXG4gICAgICByZXF1ZXN0OiBGYXN0aWZ5UmVxdWVzdCxcbiAgICApOiBQcm9taXNlPHZvaWQ+ID0+IHtcbiAgICAgIGNvbnN0IHNvY2tldCA9IGNvbm5lY3Rpb24uc29ja2V0O1xuICAgICAgbGV0IHdzQ29udGV4dDogV2ViU29ja2V0Q29udGV4dDxvYmplY3QsIG9iamVjdD4gfCBudWxsID0gbnVsbDtcbiAgICAgIGxldCByYXdXczogUmV0dXJuVHlwZTxXZWJTb2NrZXRSdW50aW1lW1wicmVnaXN0ZXJDb25uZWN0aW9uXCJdPiB8IG51bGwgPSBudWxsO1xuICAgICAgbGV0IHByZVJlZ2lzdGVyUGhhc2U6IFwiZ3VhcmRcIiB8IFwicXVlcnlcIiB8IFwicmVnaXN0ZXJcIiB8IFwiaGFuZGxlclwiID0gXCJndWFyZFwiO1xuICAgICAgbGV0IHRyYWNlQ29udGV4dDogV2ViU29ja2V0VGVsZW1ldHJ5Q29ubmVjdGlvbkNvbnRleHQgPSB7fTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgdHJhY2VDb250ZXh0ID0gdGhpcy53ZWJzb2NrZXRSdW50aW1lLnRlbGVtZXRyeUNvbnRyb2xsZXIuY3JlYXRlQ29ubmVjdGlvbkNvbnRleHQoe1xuICAgICAgICAgIGhlYWRlcnM6IHJlcXVlc3QuaGVhZGVycyxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgcHJlUmVnaXN0ZXJQaGFzZSA9IFwicXVlcnlcIjtcbiAgICAgICAgY29uc3QgcmVxQm9keSA9IGF3YWl0IHRoaXMucGFyc2VXZWJTb2NrZXRSZXF1ZXN0UGFyYW1zKGFwaSwgcmVxdWVzdCk7XG4gICAgICAgIHByZVJlZ2lzdGVyUGhhc2UgPSBcInJlZ2lzdGVyXCI7XG4gICAgICAgIHJhd1dzID0gdGhpcy53ZWJzb2NrZXRSdW50aW1lLnJlZ2lzdGVyQ29ubmVjdGlvbihzb2NrZXQsIHtcbiAgICAgICAgICBvdXRFdmVudHM6IGFwaS53ZWJzb2NrZXRPcHRpb25zIS5vdXRFdmVudHMsXG4gICAgICAgICAgaW5FdmVudHM6IGFwaS53ZWJzb2NrZXRPcHRpb25zIS5pbkV2ZW50cyxcbiAgICAgICAgICBuYW1lc3BhY2U6IGFwaS53ZWJzb2NrZXRPcHRpb25zIS5uYW1lc3BhY2UsXG4gICAgICAgICAgaGVhcnRiZWF0OiBhcGkud2Vic29ja2V0T3B0aW9ucyEuaGVhcnRiZWF0LFxuICAgICAgICAgIGFjdGl2ZTogZmFsc2UsXG4gICAgICAgICAgdHJhY2VJZDogdHJhY2VDb250ZXh0LnRyYWNlSWQsXG4gICAgICAgICAgc3BhbklkOiB0cmFjZUNvbnRleHQuc3BhbklkLFxuICAgICAgICAgIHBhcmVudFNwYW5JZDogdHJhY2VDb250ZXh0LnBhcmVudFNwYW5JZCxcbiAgICAgICAgICBzYW1wbGVkOiB0cmFjZUNvbnRleHQuc2FtcGxlZCxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3Qgc2NvcGVkV3MgPSB0aGlzLmNyZWF0ZVNjb3BlZFdlYlNvY2tldENvbm5lY3Rpb24ocmF3V3MsICgpID0+IHdzQ29udGV4dCk7XG4gICAgICAgIHdzQ29udGV4dCA9IGF3YWl0IHRoaXMuY3JlYXRlV2ViU29ja2V0Q29udGV4dChjb25maWcsIHJlcXVlc3QsIHNjb3BlZFdzKTtcblxuICAgICAgICBhd2FpdCB0aGlzLmFzeW5jTG9jYWxTdG9yYWdlLnJ1bih7IGNvbnRleHQ6IHdzQ29udGV4dCB9LCBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgcnVuR3VhcmRzKHtcbiAgICAgICAgICAgIGd1YXJkczogYXBpLm9wdGlvbnMuZ3VhcmRzLFxuICAgICAgICAgICAgY29uZmlnLFxuICAgICAgICAgICAgcmVxdWVzdCxcbiAgICAgICAgICAgIGFwaSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgdGhpcy53ZWJzb2NrZXRSdW50aW1lLmFjdGl2YXRlQ29ubmVjdGlvbihyYXdXcy5pZCk7XG4gICAgICAgIHByZVJlZ2lzdGVyUGhhc2UgPSBcImhhbmRsZXJcIjtcblxuICAgICAgICBjb25zdCB7IEFwaVBhcmFtVHlwZSB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vdHlwZXMvdHlwZXNcIik7XG4gICAgICAgIGNvbnN0IGFyZ3MgPSBhcGkucGFyYW1ldGVycy5tYXAoKHBhcmFtKSA9PiB7XG4gICAgICAgICAgaWYgKEFwaVBhcmFtVHlwZS5pc0NvbnRleHQocGFyYW0udHlwZSkpIHtcbiAgICAgICAgICAgIHJldHVybiB3c0NvbnRleHQ7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIHJlcUJvZHkuZ2V0KHBhcmFtLm5hbWUpO1xuICAgICAgICB9KTtcblxuICAgICAgICBhd2FpdCB0aGlzLmFzeW5jTG9jYWxTdG9yYWdlLnJ1bih7IGNvbnRleHQ6IHdzQ29udGV4dCB9LCBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgYXdhaXQgdGhpcy5pbnZva2VNb2RlbE1ldGhvZChhcGksIGFyZ3MpO1xuICAgICAgICB9KTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIGNvbnN0IGNsb3NlRGVzY3JpcHRvciA9IHJlc29sdmVXZWJTb2NrZXRDbG9zZURlc2NyaXB0b3IoZXJyb3IpO1xuICAgICAgICBpZiAoIXJhd1dzKSB7XG4gICAgICAgICAgdGhpcy53ZWJzb2NrZXRSdW50aW1lLnRlbGVtZXRyeUNvbnRyb2xsZXIuZW1pdCh7XG4gICAgICAgICAgICBuYW1lOiBcIndzLmNvbm5lY3Rpb24ucmVqZWN0ZWRcIixcbiAgICAgICAgICAgIGxldmVsOiBjbG9zZURlc2NyaXB0b3IubG9nTGV2ZWwgPT09IFwid2FyblwiID8gXCJ3YXJuXCIgOiBcImVycm9yXCIsXG4gICAgICAgICAgICBkZXRhaWw6IHtcbiAgICAgICAgICAgICAgcmVhc29uOiBwcmVSZWdpc3RlclBoYXNlLFxuICAgICAgICAgICAgICBjb2RlOiBjbG9zZURlc2NyaXB0b3IuY29kZSxcbiAgICAgICAgICAgICAgcGF0aDogYXBpLnBhdGgsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgdHJhY2VJZDogdHJhY2VDb250ZXh0LnRyYWNlSWQsXG4gICAgICAgICAgICBzcGFuSWQ6IHRyYWNlQ29udGV4dC5zcGFuSWQsXG4gICAgICAgICAgICBwYXJlbnRTcGFuSWQ6IHRyYWNlQ29udGV4dC5wYXJlbnRTcGFuSWQsXG4gICAgICAgICAgICBzYW1wbGVkOiB0cmFjZUNvbnRleHQuc2FtcGxlZCxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChyYXdXcykge1xuICAgICAgICAgIHJhd1dzLmNsb3NlKGNsb3NlRGVzY3JpcHRvci5jb2RlLCBjbG9zZURlc2NyaXB0b3IucmVhc29uKTtcbiAgICAgICAgfSBlbHNlIGlmIChzb2NrZXQucmVhZHlTdGF0ZSA8IDIpIHtcbiAgICAgICAgICBzb2NrZXQuY2xvc2UoY2xvc2VEZXNjcmlwdG9yLmNvZGUsIGNsb3NlRGVzY3JpcHRvci5yZWFzb24pO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuc2VydmVyPy5sb2cpIHtcbiAgICAgICAgICBjb25zdCBwYXlsb2FkID0ge1xuICAgICAgICAgICAgZXJyOiBlcnJvcixcbiAgICAgICAgICAgIG1vZGVsTmFtZTogYXBpLm1vZGVsTmFtZSxcbiAgICAgICAgICAgIG1ldGhvZE5hbWU6IGFwaS5tZXRob2ROYW1lLFxuICAgICAgICAgICAgcGF0aDogYXBpLnBhdGgsXG4gICAgICAgICAgfTtcbiAgICAgICAgICBpZiAoY2xvc2VEZXNjcmlwdG9yLmxvZ0xldmVsID09PSBcIndhcm5cIikge1xuICAgICAgICAgICAgdGhpcy5zZXJ2ZXIubG9nLndhcm4ocGF5bG9hZCwgY2xvc2VEZXNjcmlwdG9yLnJlYXNvbik7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuc2VydmVyLmxvZy5lcnJvcihwYXlsb2FkLCBjbG9zZURlc2NyaXB0b3IucmVhc29uKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaWYgKGNsb3NlRGVzY3JpcHRvci5sb2dMZXZlbCA9PT0gXCJ3YXJuXCIpIHtcbiAgICAgICAgICAgIGNvbnNvbGUud2FybihjbG9zZURlc2NyaXB0b3IucmVhc29uLCBlcnJvcik7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoY2xvc2VEZXNjcmlwdG9yLnJlYXNvbiwgZXJyb3IpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH07XG4gIH1cblxuICAvLyBvbk1lc3NhZ2Uvb25DbG9zZeyymOufvCDri6TrpbggdGlja+yXkOyEnCDsi6TtlonrkJjripQgY2FsbGJhY2vsnYAgQUxTIGNvbnRleHTqsIAg64GK6riw66+A66GcIHdyYXBwZXLsl5DshJwgYGFzeW5jTG9jYWxTdG9yYWdlLnJ1bmDsnLzroZwg64uk7IucIOqwkOyLuCDrs7Xsm5DtlahcbiAgLy8gcHVibGlzaC9qb2luL2xlYXZlL3NldFVzZXJJZCDqsJnsnYAg7KaJ7IucIOyLpO2WiSBBUEnripQg64uo7IicIOychOyehOunjCDtlZjqs6AsIGRlZmVycmVkIGNhbGxiYWNr7JeQ66eMIGNvbnRleHQg67O17JuQ7J2EIOyggeyaqe2VqFxuICBwcml2YXRlIGNyZWF0ZVNjb3BlZFdlYlNvY2tldENvbm5lY3Rpb248VE91dCBleHRlbmRzIG9iamVjdCwgVEluIGV4dGVuZHMgb2JqZWN0PihcbiAgICB3czogV2ViU29ja2V0Q29ubmVjdGlvbjxUT3V0LCBUSW4+LFxuICAgIGdldENvbnRleHQ6ICgpID0+IFdlYlNvY2tldENvbnRleHQgfCBudWxsLFxuICApOiBXZWJTb2NrZXRDb25uZWN0aW9uPFRPdXQsIFRJbj4ge1xuICAgIGNvbnN0IHRlbGVtZXRyeUNvbnRyb2xsZXIgPSB0aGlzLndlYnNvY2tldFJ1bnRpbWVWYWx1ZT8udGVsZW1ldHJ5Q29udHJvbGxlcjtcbiAgICBjb25zdCBydW5JbkNvbnRleHQgPSA8VD4oY2FsbGJhY2s6ICgpID0+IFQpOiBUID0+IHtcbiAgICAgIGNvbnN0IGNvbnRleHQgPSBnZXRDb250ZXh0KCk7XG4gICAgICBpZiAoIWNvbnRleHQpIHtcbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrKCk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0aGlzLmFzeW5jTG9jYWxTdG9yYWdlLnJ1bih7IGNvbnRleHQgfSwgY2FsbGJhY2spO1xuICAgIH07XG5cbiAgICByZXR1cm4ge1xuICAgICAgZ2V0IGlkKCkge1xuICAgICAgICByZXR1cm4gd3MuaWQ7XG4gICAgICB9LFxuICAgICAgZ2V0IG5hbWVzcGFjZSgpIHtcbiAgICAgICAgcmV0dXJuIHdzLm5hbWVzcGFjZTtcbiAgICAgIH0sXG4gICAgICBnZXQgY2xvc2VkKCkge1xuICAgICAgICByZXR1cm4gd3MuY2xvc2VkO1xuICAgICAgfSxcbiAgICAgIGdldCB1c2VySWQoKSB7XG4gICAgICAgIHJldHVybiB3cy51c2VySWQ7XG4gICAgICB9LFxuICAgICAgdHJhbnNwb3J0OiBcIndzXCIsXG4gICAgICBwdWJsaXNoVW50eXBlZChldmVudCwgZGF0YSkge1xuICAgICAgICB3cy5wdWJsaXNoVW50eXBlZChldmVudCwgZGF0YSk7XG4gICAgICB9LFxuICAgICAgY2xvc2UoY29kZSwgcmVhc29uKSB7XG4gICAgICAgIHdzLmNsb3NlKGNvZGUsIHJlYXNvbik7XG4gICAgICB9LFxuICAgICAgb25DbG9zZShjYWxsYmFjaykge1xuICAgICAgICB3cy5vbkNsb3NlKCgpID0+IHJ1bkluQ29udGV4dChjYWxsYmFjaykpO1xuICAgICAgfSxcbiAgICAgIG9uTWVzc2FnZShldmVudCwgaGFuZGxlcikge1xuICAgICAgICB3cy5vbk1lc3NhZ2UoZXZlbnQsIChkYXRhLCBtZXNzYWdlVHJhY2VDb250ZXh0KSA9PlxuICAgICAgICAgIHJ1bkluQ29udGV4dChhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBldmVudE5hbWUgPSBTdHJpbmcoZXZlbnQpO1xuICAgICAgICAgICAgY29uc3QgdHJhY2VDb250ZXh0ID0gbWVzc2FnZVRyYWNlQ29udGV4dCA/PyBnZXRXZWJTb2NrZXRUZWxlbWV0cnlDb250ZXh0KHdzKTtcbiAgICAgICAgICAgIGNvbnN0IHN0YXJ0ZWRBdCA9IHBlcmZvcm1hbmNlLm5vdygpO1xuXG4gICAgICAgICAgICB0ZWxlbWV0cnlDb250cm9sbGVyPy5lbWl0KHtcbiAgICAgICAgICAgICAgbmFtZTogXCJ3cy5oYW5kbGVyLnN0YXJ0ZWRcIixcbiAgICAgICAgICAgICAgbGV2ZWw6IFwiZGVidWdcIixcbiAgICAgICAgICAgICAgY29ubmVjdGlvbklkOiB3cy5pZCxcbiAgICAgICAgICAgICAgbmFtZXNwYWNlOiB3cy5uYW1lc3BhY2UsXG4gICAgICAgICAgICAgIHVzZXJJZDogd3MudXNlcklkLFxuICAgICAgICAgICAgICBkZXRhaWw6IHsgZXZlbnQ6IGV2ZW50TmFtZSB9LFxuICAgICAgICAgICAgICAuLi50cmFjZUNvbnRleHQsXG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgaGFuZGxlcihkYXRhLCBtZXNzYWdlVHJhY2VDb250ZXh0KTtcbiAgICAgICAgICAgICAgY29uc3QgZHVyYXRpb25NcyA9IHBlcmZvcm1hbmNlLm5vdygpIC0gc3RhcnRlZEF0O1xuICAgICAgICAgICAgICB0ZWxlbWV0cnlDb250cm9sbGVyPy5lbWl0KHtcbiAgICAgICAgICAgICAgICBuYW1lOiBcIndzLmhhbmRsZXIuY29tcGxldGVkXCIsXG4gICAgICAgICAgICAgICAgbGV2ZWw6IFwiZGVidWdcIixcbiAgICAgICAgICAgICAgICBjb25uZWN0aW9uSWQ6IHdzLmlkLFxuICAgICAgICAgICAgICAgIG5hbWVzcGFjZTogd3MubmFtZXNwYWNlLFxuICAgICAgICAgICAgICAgIHVzZXJJZDogd3MudXNlcklkLFxuICAgICAgICAgICAgICAgIGRldGFpbDogeyBldmVudDogZXZlbnROYW1lIH0sXG4gICAgICAgICAgICAgICAgLi4udHJhY2VDb250ZXh0LFxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgdGVsZW1ldHJ5Q29udHJvbGxlcj8ucmVjb3JkU3Bhbih7XG4gICAgICAgICAgICAgICAgb3BlcmF0aW9uTmFtZTogXCJ3cy5tZXNzYWdlLnByb2Nlc3NcIixcbiAgICAgICAgICAgICAgICBraW5kOiBcImludGVybmFsXCIsXG4gICAgICAgICAgICAgICAgZHVyYXRpb25NcyxcbiAgICAgICAgICAgICAgICBzdGF0dXM6IFwidW5zZXRcIixcbiAgICAgICAgICAgICAgICBjb25uZWN0aW9uSWQ6IHdzLmlkLFxuICAgICAgICAgICAgICAgIG5hbWVzcGFjZTogd3MubmFtZXNwYWNlLFxuICAgICAgICAgICAgICAgIHVzZXJJZDogd3MudXNlcklkLFxuICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXM6IHsgZXZlbnQ6IGV2ZW50TmFtZSB9LFxuICAgICAgICAgICAgICAgIC4uLnRyYWNlQ29udGV4dCxcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICBjb25zdCBkdXJhdGlvbk1zID0gcGVyZm9ybWFuY2Uubm93KCkgLSBzdGFydGVkQXQ7XG4gICAgICAgICAgICAgIHRlbGVtZXRyeUNvbnRyb2xsZXI/LmVtaXQoe1xuICAgICAgICAgICAgICAgIG5hbWU6IFwid3MuaGFuZGxlci5mYWlsZWRcIixcbiAgICAgICAgICAgICAgICBsZXZlbDogXCJlcnJvclwiLFxuICAgICAgICAgICAgICAgIGNvbm5lY3Rpb25JZDogd3MuaWQsXG4gICAgICAgICAgICAgICAgbmFtZXNwYWNlOiB3cy5uYW1lc3BhY2UsXG4gICAgICAgICAgICAgICAgdXNlcklkOiB3cy51c2VySWQsXG4gICAgICAgICAgICAgICAgZGV0YWlsOiB7IGV2ZW50OiBldmVudE5hbWUgfSxcbiAgICAgICAgICAgICAgICAuLi50cmFjZUNvbnRleHQsXG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICB0ZWxlbWV0cnlDb250cm9sbGVyPy5yZWNvcmRTcGFuKHtcbiAgICAgICAgICAgICAgICBvcGVyYXRpb25OYW1lOiBcIndzLm1lc3NhZ2UucHJvY2Vzc1wiLFxuICAgICAgICAgICAgICAgIGtpbmQ6IFwiaW50ZXJuYWxcIixcbiAgICAgICAgICAgICAgICBkdXJhdGlvbk1zLFxuICAgICAgICAgICAgICAgIHN0YXR1czogXCJlcnJvclwiLFxuICAgICAgICAgICAgICAgIGNvbm5lY3Rpb25JZDogd3MuaWQsXG4gICAgICAgICAgICAgICAgbmFtZXNwYWNlOiB3cy5uYW1lc3BhY2UsXG4gICAgICAgICAgICAgICAgdXNlcklkOiB3cy51c2VySWQsXG4gICAgICAgICAgICAgICAgYXR0cmlidXRlczogeyBldmVudDogZXZlbnROYW1lIH0sXG4gICAgICAgICAgICAgICAgZXJyb3JUeXBlOiBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubmFtZSA6IHJ1bnRpbWVUeXBlT2YoZXJyb3IpLFxuICAgICAgICAgICAgICAgIC4uLnRyYWNlQ29udGV4dCxcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pLFxuICAgICAgICApO1xuICAgICAgfSxcbiAgICAgIHB1Ymxpc2goZXZlbnQsIGRhdGEpIHtcbiAgICAgICAgd3MucHVibGlzaChldmVudCwgZGF0YSk7XG4gICAgICB9LFxuICAgICAgd2FpdEZvckNsb3NlKCkge1xuICAgICAgICByZXR1cm4gd3Mud2FpdEZvckNsb3NlKCk7XG4gICAgICB9LFxuICAgICAgam9pbihyb29tSWQpIHtcbiAgICAgICAgd3Muam9pbihyb29tSWQpO1xuICAgICAgfSxcbiAgICAgIGxlYXZlKHJvb21JZCkge1xuICAgICAgICB3cy5sZWF2ZShyb29tSWQpO1xuICAgICAgfSxcbiAgICAgIHNldFVzZXJJZCh1c2VySWQpIHtcbiAgICAgICAgd3Muc2V0VXNlcklkKHVzZXJJZCk7XG4gICAgICB9LFxuICAgICAgY2xlYXJVc2VySWQoKSB7XG4gICAgICAgIHdzLmNsZWFyVXNlcklkKCk7XG4gICAgICB9LFxuICAgIH07XG4gIH1cblxuICBjcmVhdGVTY29wZWRXZWJTb2NrZXRDb25uZWN0aW9uRm9yVGVzdGluZzxUT3V0IGV4dGVuZHMgb2JqZWN0LCBUSW4gZXh0ZW5kcyBvYmplY3Q+KFxuICAgIHdzOiBXZWJTb2NrZXRDb25uZWN0aW9uPFRPdXQsIFRJbj4sXG4gICAgZ2V0Q29udGV4dDogKCkgPT4gV2ViU29ja2V0Q29udGV4dCB8IG51bGwsXG4gICk6IFdlYlNvY2tldENvbm5lY3Rpb248VE91dCwgVEluPiB7XG4gICAgcmV0dXJuIHRoaXMuY3JlYXRlU2NvcGVkV2ViU29ja2V0Q29ubmVjdGlvbih3cywgZ2V0Q29udGV4dCk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHBhcnNlV2ViU29ja2V0UmVxdWVzdFBhcmFtcyhcbiAgICBhcGk6IEV4dGVuZGVkQXBpLFxuICAgIHJlcXVlc3Q6IEZhc3RpZnlSZXF1ZXN0LFxuICApOiBQcm9taXNlPE1hcDxzdHJpbmcsIEFwaUFyZ3VtZW50Pj4ge1xuICAgIGNvbnN0IHsgZ2V0Wm9kT2JqZWN0RnJvbUFwaSB9ID0gYXdhaXQgaW1wb3J0KFwiLi9jb2RlLWNvbnZlcnRlcnNcIik7XG4gICAgY29uc3QgUmVxVHlwZSA9IGdldFpvZE9iamVjdEZyb21BcGkoYXBpLCB0aGlzLnN5bmNlci50eXBlcyk7XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgeyBmYXN0aWZ5Q2FzdGVyIH0gPSBhd2FpdCBpbXBvcnQoXCIuL2Nhc3RlclwiKTtcbiAgICAgIHJldHVybiB0b0FwaUFyZ3VtZW50TWFwKGZhc3RpZnlDYXN0ZXIoUmVxVHlwZSkucGFyc2UocmVxdWVzdC5xdWVyeSA/PyB7fSkpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGNvbnN0IHsgWm9kRXJyb3IgfSA9IGF3YWl0IGltcG9ydChcInpvZFwiKTtcbiAgICAgIGlmIChlIGluc3RhbmNlb2YgWm9kRXJyb3IpIHtcbiAgICAgICAgY29uc3QgeyBodW1hbml6ZVpvZEVycm9yIH0gPSBhd2FpdCBpbXBvcnQoXCIuLi91dGlscy96b2QtZXJyb3JcIik7XG4gICAgICAgIGNvbnN0IG1lc3NhZ2VzID0gaHVtYW5pemVab2RFcnJvcihlKVxuICAgICAgICAgIC5tYXAoKGlzc3VlKSA9PiBpc3N1ZS5tZXNzYWdlKVxuICAgICAgICAgIC5qb2luKFwiIFwiKTtcbiAgICAgICAgY29uc3QgeyBCYWRSZXF1ZXN0RXhjZXB0aW9uIH0gPSBhd2FpdCBpbXBvcnQoXCIuLi9leGNlcHRpb25zL3NvLWV4Y2VwdGlvbnNcIik7XG4gICAgICAgIHRocm93IG5ldyBCYWRSZXF1ZXN0RXhjZXB0aW9uKFxuICAgICAgICAgIC8qIFNBRkVUWTogQVBJIOuNsOy9lOugiOydtO2EsOyZgCBab2Qg6rKA7Kad6riwIOuTseuhnSDqs4Tslb3snbQg7J20IOqwkuydmCDtg4DsnoXsnYQg67O07J6l7ZWc64ukLiAqLyBtZXNzYWdlcyBhcyBMb2NhbGl6ZWRTdHJpbmcsXG4gICAgICAgICAge1xuICAgICAgICAgICAgem9kRXJyb3I6IGUsXG4gICAgICAgICAgfSxcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgdGhyb3cgZTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVVJM7JeQ7IScIHBhdGggcGFyYW1z66W8IOy2lOy2nO2VqeuLiOuLpC5cbiAgICog7JiIOiBwYXR0ZXJuPVwiL2FkbWluL2NvbXBhbmllcy86Y29tcGFueUlkXCIsIHVybD1cIi9hZG1pbi9jb21wYW5pZXMvMTIzXCIg4oaSIHsgY29tcGFueUlkOiBcIjEyM1wiIH1cbiAgICovXG4gIHByaXZhdGUgZXh0cmFjdFBhdGhQYXJhbXMocGF0dGVybjogc3RyaW5nLCB1cmw6IHN0cmluZykge1xuICAgIGNvbnN0IHBhdHRlcm5QYXJ0cyA9IHBhdHRlcm4uc3BsaXQoXCIvXCIpLmZpbHRlcihCb29sZWFuKTtcbiAgICBjb25zdCB1cmxQYXJ0cyA9IHRoaXMuZ2V0UGF0aG5hbWVGcm9tVXJsKHVybCkuc3BsaXQoXCIvXCIpLmZpbHRlcihCb29sZWFuKTtcbiAgICBjb25zdCBwYXJhbXM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7fTtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcGF0dGVyblBhcnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAocGF0dGVyblBhcnRzW2ldLnN0YXJ0c1dpdGgoXCI6XCIpKSB7XG4gICAgICAgIHBhcmFtc1twYXR0ZXJuUGFydHNbaV0uc2xpY2UoMSldID0gdXJsUGFydHNbaV07XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBwYXJhbXM7XG4gIH1cblxuICBwcml2YXRlIGlzUGF0aFBhdHRlcm5NYXRjaChwYXR0ZXJuOiBzdHJpbmcsIHVybDogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgY29uc3QgcGF0dGVyblBhcnRzID0gcGF0dGVybi5zcGxpdChcIi9cIikuZmlsdGVyKEJvb2xlYW4pO1xuICAgIGNvbnN0IHVybFBhcnRzID0gdGhpcy5nZXRQYXRobmFtZUZyb21VcmwodXJsKS5zcGxpdChcIi9cIikuZmlsdGVyKEJvb2xlYW4pO1xuXG4gICAgaWYgKHBhdHRlcm5QYXJ0cy5sZW5ndGggIT09IHVybFBhcnRzLmxlbmd0aCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcGF0dGVyblBhcnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBwYXR0ZXJuUGFydCA9IHBhdHRlcm5QYXJ0c1tpXTtcbiAgICAgIGNvbnN0IHVybFBhcnQgPSB1cmxQYXJ0c1tpXTtcbiAgICAgIGlmIChwYXR0ZXJuUGFydC5zdGFydHNXaXRoKFwiOlwiKSkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGlmIChwYXR0ZXJuUGFydCAhPT0gdXJsUGFydCkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBwcml2YXRlIGdldFBhdGhuYW1lRnJvbVVybCh1cmw6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHVybC5zcGxpdChcIj9cIilbMF07XG4gIH1cblxuICBwcml2YXRlIHJlc29sdmVQYXRoV2l0aGluQmFzZURpcihiYXNlRGlyOiBzdHJpbmcsIGlucHV0UGF0aDogc3RyaW5nKTogc3RyaW5nIHwgbnVsbCB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGRlY29kZWQgPSBkZWNvZGVVUklDb21wb25lbnQoaW5wdXRQYXRoKS5yZXBsYWNlKC9cXFxcL2csIFwiL1wiKTtcbiAgICAgIGlmIChkZWNvZGVkLmluY2x1ZGVzKFwiXFwwXCIpKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuICAgICAgY29uc3QgcmVsYXRpdmVQYXRoID0gZGVjb2RlZC5yZXBsYWNlKC9eXFwvKy8sIFwiXCIpO1xuICAgICAgY29uc3QgcmVzb2x2ZWRQYXRoID0gcGF0aC5yZXNvbHZlKGJhc2VEaXIsIHJlbGF0aXZlUGF0aCk7XG4gICAgICBjb25zdCByZWxhdGl2ZUZyb21CYXNlID0gcGF0aC5yZWxhdGl2ZShiYXNlRGlyLCByZXNvbHZlZFBhdGgpO1xuICAgICAgaWYgKHJlbGF0aXZlRnJvbUJhc2Uuc3RhcnRzV2l0aChcIi4uXCIpIHx8IHBhdGguaXNBYnNvbHV0ZShyZWxhdGl2ZUZyb21CYXNlKSkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXNvbHZlZFBhdGg7XG4gICAgfSBjYXRjaCB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQVBJIOydkeuLteyXkCDsoIHsmqntlaAgQ2FjaGUtQ29udHJvbCDshKTsoJXsnYQg6rKw7KCV7ZWp64uI64ukLlxuICAgKiDsmrDshKDsiJzsnIQ6IOqwnOuzhCDsp4DsoJUgPiBjYWNoZUNvbnRyb2xIYW5kbGVyXG4gICAqL1xuICBwcml2YXRlIGdldEFwaUNhY2hlQ29udHJvbChcbiAgICBhcGk6IEV4dGVuZGVkQXBpLFxuICAgIHJlcXVlc3Q6IEZhc3RpZnlSZXF1ZXN0LFxuICAgIGNvbmZpZzogU29uYW11RmFzdGlmeUNvbmZpZyxcbiAgKSB7XG4gICAgLy8g642w7L2U66CI7J207YSwIOyEpOyglSDsmrDshKBcbiAgICBpZiAoYXBpLm9wdGlvbnMuY2FjaGVDb250cm9sKSB7XG4gICAgICByZXR1cm4gYXBpLm9wdGlvbnMuY2FjaGVDb250cm9sO1xuICAgIH1cblxuICAgIC8vIOyghOyXrSDtlbjrk6Trn6xcbiAgICBpZiAoY29uZmlnLmNhY2hlQ29udHJvbEhhbmRsZXIpIHtcbiAgICAgIGNvbnN0IGNhY2hlUmVxOiBDYWNoZUNvbnRyb2xSZXF1ZXN0ID0ge1xuICAgICAgICB0eXBlOiBcImFwaVwiLFxuICAgICAgICB1cmw6IHJlcXVlc3QudXJsLFxuICAgICAgICBwYXRoOiByZXF1ZXN0LnJvdXRlT3B0aW9ucz8udXJsID8/IHJlcXVlc3QudXJsLnNwbGl0KFwiP1wiKVswXSxcbiAgICAgICAgbWV0aG9kOiByZXF1ZXN0Lm1ldGhvZCxcbiAgICAgICAgYXBpLFxuICAgICAgfTtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGNvbmZpZy5jYWNoZUNvbnRyb2xIYW5kbGVyKGNhY2hlUmVxKTtcbiAgICAgIGlmIChyZXN1bHQpIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICAvKipcbiAgICogU1NS7JqpIEFQSSDtmLjstpwgKEhUVFAg7Jik67KE7Zek65OcIOyXhuydtCDsp4HsoJEg7Zi47LacKVxuICAgKiBjcmVhdGVBcGlIYW5kbGVy7J2YIOuhnOyngeydhCDsnqzsgqzsmqntlZjrkJgsIHJlcXVlc3Qg7YyM7IuxIOuMgOyLoCBwYXJhbXMg7KeB7KCRIOyCrOyaqVxuICAgKi9cbiAgYXN5bmMgaW52b2tlQXBpRm9yU1NSKFxuICAgIGFwaTogRXh0ZW5kZWRBcGksXG4gICAgcGFyYW1zOiBhbnlbXSxcbiAgICBjb25maWc6IFNvbmFtdUZhc3RpZnlDb25maWcsXG4gICAgcmVxdWVzdDogRmFzdGlmeVJlcXVlc3QsXG4gICAgcmVwbHk6IEZhc3RpZnlSZXBseSxcbiAgKTogUHJvbWlzZTxBcGlNZXRob2RSZXN1bHQ+IHtcbiAgICAvLyBDb250ZXh0IOyDneyEsSAo6riw7KG0IOuplOyGjOuTnCDsnqzsgqzsmqkpXG4gICAgY29uc3QgY29udGV4dCA9IGF3YWl0IHRoaXMuY3JlYXRlQ29udGV4dChjb25maWcsIHJlcXVlc3QsIHJlcGx5KTtcblxuICAgIHJldHVybiB0aGlzLmFzeW5jTG9jYWxTdG9yYWdlLnJ1bih7IGNvbnRleHQgfSwgYXN5bmMgKCkgPT4ge1xuICAgICAgLy8gYXJncyDsg53shLE6IENvbnRleHQg7YyM652866+47YSw64qUIOyjvOyehSwg64KY66i47KeA64qUIHBhcmFtc+yXkOyEnCDqsIDsoLjsmKTquLBcbiAgICAgIGNvbnN0IHsgQXBpUGFyYW1UeXBlIH0gPSBhd2FpdCBpbXBvcnQoXCIuLi90eXBlcy90eXBlc1wiKTtcbiAgICAgIGxldCBwYXJhbXNJbmRleCA9IDA7XG4gICAgICBjb25zdCBhcmdzID0gYXBpLnBhcmFtZXRlcnMubWFwKChwYXJhbSkgPT4ge1xuICAgICAgICBpZiAoQXBpUGFyYW1UeXBlLmlzQ29udGV4dChwYXJhbS50eXBlKSkge1xuICAgICAgICAgIHJldHVybiBjb250ZXh0O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBwYXJhbXNbcGFyYW1zSW5kZXgrK107XG4gICAgICB9KTtcblxuICAgICAgLy8g66qo6424IOuplOyEnOuTnCDtmLjstpwgKOq4sOyhtCDrqZTshJzrk5wg7J6s7IKs7JqpKVxuICAgICAgcmV0dXJuIHRoaXMuaW52b2tlTW9kZWxNZXRob2QoYXBpLCBhcmdzLCByZXBseSk7XG4gICAgfSk7XG4gIH1cblxuICBhc3luYyBoYW5kbGVEZXZBcGlSZXF1ZXN0Rm9yVGVzdGluZyhyZXF1ZXN0OiBGYXN0aWZ5UmVxdWVzdCwgY29uZmlnOiBTb25hbXVGYXN0aWZ5Q29uZmlnKSB7XG4gICAgcmV0dXJuIGF3YWl0IHRoaXMuaGFuZGxlRGV2QXBpUmVxdWVzdChyZXF1ZXN0LCBjb25maWcpO1xuICB9XG5cbiAgLy8gV1Mg6rK966Gc7JeQ7ISc64qUIEhUVFAgcmVwbHnqsIAg7JeG7Jy866+A66GcIHJlcGx566W8IG9wdGlvbmFs66GcIOuwm+yVhCDqs7XthrUg7Zi47LacIOqyveuhnOulvCDsnKDsp4DtlahcbiAgYXN5bmMgaW52b2tlTW9kZWxNZXRob2QoXG4gICAgYXBpOiBFeHRlbmRlZEFwaSxcbiAgICBhcmdzOiB1bmtub3duW10sXG4gICAgcmVwbHk/OiBGYXN0aWZ5UmVwbHksXG4gICAgbW9kZWxzOiBMb2FkZWRNb2RlbHMgPSB0aGlzLnN5bmNlci5tb2RlbHMsXG4gICk6IFByb21pc2U8QXBpTWV0aG9kUmVzdWx0PiB7XG4gICAgY29uc3QgbW9kZWwgPSBtb2RlbHNbYXBpLm1vZGVsTmFtZV07XG4gICAgaWYgKG1vZGVsID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgTW9kZWwgbm90IGZvdW5kOiAke2FwaS5tb2RlbE5hbWV9YCk7XG4gICAgfVxuICAgIGNvbnN0IG1ldGhvZCA9XG4gICAgICBtb2RlbFtcbiAgICAgICAgLyogU0FGRVRZOiDrj5nquLDtmZTquLDqsIAg66qo6424IO2BtOuemOyKpOyXkOyEnCDsiJjsp5HtlZwgQVBJIOuplOyEnOuTnCDsnbTrpoTrp4wg7KCE64us7ZWc64ukLiAqLyBhcGkubWV0aG9kTmFtZSBhcyBrZXlvZiB0eXBlb2YgbW9kZWxcbiAgICAgIF07XG4gICAgaWYgKCFpc0Z1bmN0aW9uVmFsdWUobWV0aG9kKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBNb2RlbCBtZXRob2Qgbm90IGZvdW5kOiAke2FwaS5tb2RlbE5hbWV9LiR7YXBpLm1ldGhvZE5hbWV9YCk7XG4gICAgfVxuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IEZ1bmN0aW9uLnByb3RvdHlwZS5hcHBseS5jYWxsKG1ldGhvZCwgbW9kZWwsIGFyZ3MpO1xuICAgIHJlcGx5Py50eXBlKGFwaS5vcHRpb25zLmNvbnRlbnRUeXBlID8/IFwiYXBwbGljYXRpb24vanNvblwiKTtcblxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICBhc3luYyBjcmVhdGVDb250ZXh0KFxuICAgIGNvbmZpZzogU29uYW11RmFzdGlmeUNvbmZpZyxcbiAgICByZXF1ZXN0OiBGYXN0aWZ5UmVxdWVzdCxcbiAgICByZXBseTogRmFzdGlmeVJlcGx5LFxuICApOiBQcm9taXNlPENvbnRleHQ+IHtcbiAgICAvLyBjcmVhdGVTU0VGYWN0b3J5IO2VqOyImOyXkCDrr7jrpqwgcmVxdWVzdOydmCBzb2NrZXTqs7wgcmVwbHnrpbwg67CU7J2465SpLlxuICAgIGNvbnN0IHsgY3JlYXRlU1NFRmFjdG9yeSB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vc3RyZWFtL3NzZVwiKTtcbiAgICBjb25zdCBjcmVhdGVTU0UgPSAoPFQgZXh0ZW5kcyBab2RPYmplY3Q+KFxuICAgICAgX3JlcXVlc3Q6IEZhc3RpZnlSZXF1ZXN0LFxuICAgICAgX3JlcGx5OiBGYXN0aWZ5UmVwbHksXG4gICAgICBfZXZlbnRzOiBULFxuICAgICkgPT4gY3JlYXRlU1NFRmFjdG9yeShfcmVxdWVzdC5zb2NrZXQsIF9yZXBseSwgX2V2ZW50cykpLmJpbmQobnVsbCwgcmVxdWVzdCwgcmVwbHkpO1xuXG4gICAgLy8gbG9jYWxlIOqwkOyngFxuICAgIGNvbnN0IGxvY2FsZSA9XG4gICAgICB0aGlzLmRldGVjdExvY2FsZShyZXF1ZXN0LmhlYWRlcnNbXCJhY2NlcHQtbGFuZ3VhZ2VcIl0sIHRoaXMuY29uZmlnLmkxOG4uc3VwcG9ydGVkTG9jYWxlcykgPz9cbiAgICAgIHRoaXMuY29uZmlnLmkxOG4uZGVmYXVsdExvY2FsZTtcblxuICAgIC8vIGF1dGggY29udGV4dCDstpTqsIBcbiAgICBjb25zdCBoZWFkZXJzID0gY29udmVydEZhc3RpZnlIZWFkZXJzVG9TdGFuZGFyZChyZXF1ZXN0LmhlYWRlcnMpO1xuICAgIGNvbnN0IHNlc3Npb24gPSAoYXdhaXQgdGhpcy5hdXRoVmFsdWU/LmFwaS5nZXRTZXNzaW9uKHsgaGVhZGVycyB9KSkgPz8gbnVsbDtcblxuICAgIGNvbnN0IGNvbnRleHQ6IENvbnRleHQgPSBhd2FpdCBQcm9taXNlLnJlc29sdmUoXG4gICAgICBjb25maWcuY29udGV4dFByb3ZpZGVyKFxuICAgICAgICB7XG4gICAgICAgICAgdHJhbnNwb3J0OiBcImh0dHBcIixcbiAgICAgICAgICByZXF1ZXN0LFxuICAgICAgICAgIHJlcGx5LFxuICAgICAgICAgIGhlYWRlcnM6IHJlcXVlc3QuaGVhZGVycyxcbiAgICAgICAgICBjcmVhdGVTU0UsXG4gICAgICAgICAgbmFpdGVTdG9yZTogbmV3IE1hcCgpLFxuICAgICAgICAgIGxvY2FsZSxcbiAgICAgICAgICAvLyBhdXRoXG4gICAgICAgICAgdXNlcjogc2Vzc2lvbj8udXNlciA/PyBudWxsLFxuICAgICAgICAgIHNlc3Npb246IHNlc3Npb24/LnNlc3Npb24gPz8gbnVsbCxcbiAgICAgICAgfSxcbiAgICAgICAgcmVxdWVzdCxcbiAgICAgICAgcmVwbHksXG4gICAgICApLFxuICAgICk7XG4gICAgcmV0dXJuIGNvbnRleHQ7XG4gIH1cblxuICAvLyBzZXNzaW9uL2xvY2FsZS9zdG9yZSDqsJnsnYAg6rO17Ya1IHN0YXRl64qUIEhUVFAgY29udGV4dOyZgCDqs7XsnKDtlZjrkJgsIHJlcGx5L2NyZWF0ZVNTRSDqsJnsnYAgSFRUUCDsoITsmqkgaGVscGVy64qUIOuFuOy2nO2VmOyngCDslYrsnYxcbiAgLy8g7IKs7Jqp7J6Q6rCAIHdlYnNvY2tldENvbnRleHRQcm92aWRlcuulvCDso7zrqbQg6re464yA66GcIOychOyehO2VmOqzoCwg7JeG7Jy866m0IOq4sOyhtCBjb250ZXh0UHJvdmlkZXLrpbwgcmVwbHkvU1NFIHN0dWLqs7wg7ZWo6ruYIOyerO2ZnOyaqe2VqFxuICBhc3luYyBjcmVhdGVXZWJTb2NrZXRDb250ZXh0KFxuICAgIGNvbmZpZzogU29uYW11RmFzdGlmeUNvbmZpZyxcbiAgICByZXF1ZXN0OiBGYXN0aWZ5UmVxdWVzdCxcbiAgICB3czogQW55V2ViU29ja2V0Q29ubmVjdGlvbixcbiAgKTogUHJvbWlzZTxXZWJTb2NrZXRDb250ZXh0PiB7XG4gICAgY29uc3QgbG9jYWxlID1cbiAgICAgIHRoaXMuZGV0ZWN0TG9jYWxlKHJlcXVlc3QuaGVhZGVyc1tcImFjY2VwdC1sYW5ndWFnZVwiXSwgdGhpcy5jb25maWcuaTE4bi5zdXBwb3J0ZWRMb2NhbGVzKSA/P1xuICAgICAgdGhpcy5jb25maWcuaTE4bi5kZWZhdWx0TG9jYWxlO1xuXG4gICAgY29uc3QgaGVhZGVycyA9IGNvbnZlcnRGYXN0aWZ5SGVhZGVyc1RvU3RhbmRhcmQocmVxdWVzdC5oZWFkZXJzKTtcbiAgICBjb25zdCBzZXNzaW9uID0gKGF3YWl0IHRoaXMuYXV0aFZhbHVlPy5hcGkuZ2V0U2Vzc2lvbih7IGhlYWRlcnMgfSkpID8/IG51bGw7XG5cbiAgICBjb25zdCBkZWZhdWx0Q29udGV4dCA9IHtcbiAgICAgIHRyYW5zcG9ydDogXCJ3c1wiIGFzIGNvbnN0LFxuICAgICAgcmVxdWVzdCxcbiAgICAgIGhlYWRlcnM6IHJlcXVlc3QuaGVhZGVycyxcbiAgICAgIHdzLFxuICAgICAgbmFpdGVTdG9yZTogbmV3IE1hcCgpLFxuICAgICAgbG9jYWxlLFxuICAgICAgdXNlcjogc2Vzc2lvbj8udXNlciA/PyBudWxsLFxuICAgICAgc2Vzc2lvbjogc2Vzc2lvbj8uc2Vzc2lvbiA/PyBudWxsLFxuICAgIH07XG5cbiAgICBpZiAoY29uZmlnLndlYnNvY2tldENvbnRleHRQcm92aWRlcikge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgLi4uKGF3YWl0IFByb21pc2UucmVzb2x2ZShjb25maWcud2Vic29ja2V0Q29udGV4dFByb3ZpZGVyKGRlZmF1bHRDb250ZXh0LCByZXF1ZXN0KSkpLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICAvLyByZXBseS9jcmVhdGVTU0Xsl5Ag7J2Y7KG07ZWY64qUIGNvbnRleHRQcm92aWRlcuqwgCDsnojsnLzrqbQg7KaJ7IucIOyXkOufrOulvCDrjZjsoLggdHJhbnNwb3J0IG1pc3VzZeulvCDruajrpqwg65Oc65+s64OEXG4gICAgY29uc3QgcmVwbHlTdHViID0gY3JlYXRlV2ViU29ja2V0UmVwbHlTdHViKCk7XG4gICAgY29uc3QgaHR0cExpa2VDb250ZXh0ID0gYXdhaXQgUHJvbWlzZS5yZXNvbHZlKFxuICAgICAgY29uZmlnLmNvbnRleHRQcm92aWRlcihcbiAgICAgICAge1xuICAgICAgICAgIHRyYW5zcG9ydDogXCJodHRwXCIsXG4gICAgICAgICAgcmVxdWVzdCxcbiAgICAgICAgICByZXBseTogcmVwbHlTdHViLFxuICAgICAgICAgIGhlYWRlcnM6IHJlcXVlc3QuaGVhZGVycyxcbiAgICAgICAgICBjcmVhdGVTU0U6IGNyZWF0ZVVuYXZhaWxhYmxlU1NFLFxuICAgICAgICAgIG5haXRlU3RvcmU6IGRlZmF1bHRDb250ZXh0Lm5haXRlU3RvcmUsXG4gICAgICAgICAgbG9jYWxlLFxuICAgICAgICAgIHVzZXI6IGRlZmF1bHRDb250ZXh0LnVzZXIsXG4gICAgICAgICAgc2Vzc2lvbjogZGVmYXVsdENvbnRleHQuc2Vzc2lvbixcbiAgICAgICAgfSxcbiAgICAgICAgcmVxdWVzdCxcbiAgICAgICAgcmVwbHlTdHViLFxuICAgICAgKSxcbiAgICApO1xuXG4gICAgY29uc3Qge1xuICAgICAgdHJhbnNwb3J0OiBfdHJhbnNwb3J0LFxuICAgICAgcmVwbHk6IF9yZXBseSxcbiAgICAgIGNyZWF0ZVNTRTogX2NyZWF0ZVNTRSxcbiAgICAgIGJ1ZmZlcmVkRmlsZXM6IF9idWZmZXJlZEZpbGVzLFxuICAgICAgdXBsb2FkZWRGaWxlczogX3VwbG9hZGVkRmlsZXMsXG4gICAgICAuLi5yZXN0XG4gICAgfSA9IGh0dHBMaWtlQ29udGV4dDtcblxuICAgIHJldHVybiB7XG4gICAgICAuLi5yZXN0LFxuICAgICAgdHJhbnNwb3J0OiBcIndzXCIsXG4gICAgICByZXF1ZXN0LFxuICAgICAgaGVhZGVyczogcmVxdWVzdC5oZWFkZXJzLFxuICAgICAgd3MsXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBY2NlcHQtTGFuZ3VhZ2Ug7Zek642U7JeQ7IScIOyngOybkO2VmOuKlCBsb2NhbGXsnYQg7LC+7Iq164uI64ukLlxuICAgKiBAZXhhbXBsZSBcImtvLUtSLGtvO3E9MC45LGVuO3E9MC44XCIg4oaSIFwia29cIlxuICAgKi9cbiAgcHJpdmF0ZSBkZXRlY3RMb2NhbGUoXG4gICAgYWNjZXB0TGFuZ3VhZ2U6IHN0cmluZyB8IHVuZGVmaW5lZCxcbiAgICBzdXBwb3J0ZWQ6IHN0cmluZ1tdLFxuICApOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICAgIGlmICghYWNjZXB0TGFuZ3VhZ2UpIHJldHVybiB1bmRlZmluZWQ7XG5cbiAgICAvLyBBY2NlcHQtTGFuZ3VhZ2U6IGtvLUtSLGtvO3E9MC45LGVuO3E9MC44XG4gICAgY29uc3QgbGFuZ3MgPSBhY2NlcHRMYW5ndWFnZS5zcGxpdChcIixcIikubWFwKChsYW5nKSA9PiB7XG4gICAgICBjb25zdCBbY29kZV0gPSBsYW5nLnNwbGl0KFwiO1wiKTtcbiAgICAgIHJldHVybiBjb2RlLnRyaW0oKS5zcGxpdChcIi1cIilbMF07IC8vIGtvLUtSIOKGkiBrb1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIGxhbmdzLmZpbmQoKGxhbmcpID0+IHN1cHBvcnRlZC5pbmNsdWRlcyhsYW5nKSk7XG4gIH1cblxuICBhc3luYyBzdGFydFdhdGNoZXIoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgLy8gd2F0Y2hlciDrqqjrk4jsnYAgZmlsZS1wYXR0ZXJucyDihpIgU29uYW11IOyInO2ZmOydhCDtlLztlZjquLAg7JyE7ZW0IGR5bmFtaWMgaW1wb3J0IO2VqeuLiOuLpC5cbiAgICBjb25zdCB7IHNldHVwV2F0Y2hlciB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vc3luY2VyL3dhdGNoZXJcIik7XG4gICAgdGhpcy53YXRjaGVyID0gYXdhaXQgc2V0dXBXYXRjaGVyKChmaWxlRXZlbnRzKSA9PiB0aGlzLnJ1bkhtclN5bmNDeWNsZShmaWxlRXZlbnRzKSk7XG4gIH1cblxuICAvKipcbiAgICogV2F0Y2hlcuqwgCAxMDBtcyBiYXRjaOuhnCDrqqjsnYAgZmlsZUV2ZW50cyDtlZjrgpjsl5Ag64yA7ZW0IO2VnCDrsojsnZggSE1SL3N5bmMg7IKs7J207YG07J2EIOuPleuLiOuLpC5cbiAgICogYmF0Y2gg7YGQ7J6JIOuNleyXkCDtlZwg7Iuc7KCQ7JeQIO2VmOuCmOunjCDsi6TtlonrkKjsnbQg67O07J6l65Cp64uI64ukIChldmVudC1iYXRjaGVy6rCAIOyngeugrO2ZlCkuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIHJ1bkhtclN5bmNDeWNsZShmaWxlRXZlbnRzOiBNYXA8QWJzb2x1dGVQYXRoLCBcImNoYW5nZVwiIHwgXCJhZGRcIj4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBzdGFydGVkQXQgPSBEYXRlLm5vdygpO1xuXG4gICAgZm9yIChjb25zdCBbZmlsZVBhdGgsIGV2ZW50XSBvZiBmaWxlRXZlbnRzKSB7XG4gICAgICBjb25zdCByZWxhdGl2ZVBhdGggPSBwYXRoLnJlbGF0aXZlKHRoaXMuYXBwUm9vdFBhdGgsIGZpbGVQYXRoKTtcbiAgICAgIGNvbnNvbGUubG9nKGNoYWxrLmJvbGQoYERldGVjdGVkKCR7ZXZlbnR9KTogJHtjaGFsay5ibHVlKHJlbGF0aXZlUGF0aCl9YCkpO1xuICAgIH1cblxuICAgIC8vIOuzuOyytDog67OA6rK9IO2doeyImCArIOyytO2BrOyErCDqsLHsi6AuXG4gICAgYXdhaXQgdGhpcy5zeW5jZXIuaG1yQW5kU3luYyhmaWxlRXZlbnRzKTtcbiAgICBhd2FpdCB0aGlzLnN5bmNlci5yZW5ld0NoZWNrc3VtcygpO1xuXG4gICAgY29uc3QgdG90YWxUaW1lID0gRGF0ZS5ub3coKSAtIHN0YXJ0ZWRBdDtcbiAgICBjb25zdCBtc2cgPSBgSE1SIERvbmUhICR7Y2hhbGsuYm9sZC53aGl0ZShgJHt0b3RhbFRpbWV9bXNgKX1gO1xuICAgIGNvbnNvbGUubG9nKGNoYWxrLmJsYWNrLmJnR3JlZW4oY2VudGVyVGV4dChtc2cpKSk7XG4gIH1cblxuICAvKlxuICAgICBBIGZ1bmN0aW9uIHRoYXQgYXV0b21hdGljYWxseSBoYW5kbGVzIGluaXQgYW5kIGRlc3Ryb3kgd2hlbiB1c2luZyBTb25hbXUgdmlhIHNjcmlwdHMuXG4gICovXG4gIGFzeW5jIHJ1blNjcmlwdChmbjogKCkgPT4gUHJvbWlzZTx2b2lkPikge1xuICAgIGF3YWl0IHRoaXMuaW5pdCh0cnVlLCBmYWxzZSwgdW5kZWZpbmVkLCBmYWxzZSk7XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IGZuKCk7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIGF3YWl0IHRoaXMuZGVzdHJveSgpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgcmVnaXN0ZXJQbHVnaW5zKHNlcnZlcjogRmFzdGlmeUluc3RhbmNlLCBwbHVnaW5zOiBTb25hbXVTZXJ2ZXJPcHRpb25zW1wicGx1Z2luc1wiXSkge1xuICAgIGlmICghcGx1Z2lucykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIGNvbXByZXNzIO2UjOufrOq3uOyduOydgCDri6Trpbgg7ZSM65+s6re47J2467O064ukIOuovOyggCDrk7HroZ3rkJjslrTslbwg7ZWp64uI64ukLlxuICAgIGlmIChwbHVnaW5zLmNvbXByZXNzKSB7XG4gICAgICBjb25zdCBjb21wcmVzc1BsdWdpbiA9IChhd2FpdCBpbXBvcnQoXCJAZmFzdGlmeS9jb21wcmVzc1wiKSkuZGVmYXVsdDtcbiAgICAgIGNvbnN0IGRlZmF1bHRPcHRpb25zID0ge1xuICAgICAgICB0aHJlc2hvbGQ6IDEwMjQsXG4gICAgICAgIGVuY29kaW5nczogLyogU0FGRVRZOiBBUEkg642w7L2U66CI7J207YSw7JmAIFpvZCDqsoDspp3quLAg65Ox66GdIOqzhOyVveydtCDsnbQg6rCS7J2YIO2DgOyeheydhCDrs7TsnqXtlZzri6QuICovIFtcbiAgICAgICAgICBcImJyXCIsXG4gICAgICAgICAgXCJnemlwXCIsXG4gICAgICAgICAgXCJkZWZsYXRlXCIsXG4gICAgICAgIF0gYXMgKFwiYnJcIiB8IFwiZ3ppcFwiIHwgXCJkZWZsYXRlXCIpW10sXG4gICAgICB9O1xuXG4gICAgICBpZiAocGx1Z2lucy5jb21wcmVzcyA9PT0gdHJ1ZSkge1xuICAgICAgICBzZXJ2ZXIucmVnaXN0ZXIoY29tcHJlc3NQbHVnaW4sIGRlZmF1bHRPcHRpb25zKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHNlcnZlci5yZWdpc3Rlcihjb21wcmVzc1BsdWdpbiwge1xuICAgICAgICAgIC4uLmRlZmF1bHRPcHRpb25zLFxuICAgICAgICAgIC4uLnBsdWdpbnMuY29tcHJlc3MsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IHBsdWdpbnNNb2R1bGVzID0ge1xuICAgICAgY29yczogXCJAZmFzdGlmeS9jb3JzXCIsXG4gICAgICBmb3JtYm9keTogXCJAZmFzdGlmeS9mb3JtYm9keVwiLFxuICAgICAgbXVsdGlwYXJ0OiBcIkBmYXN0aWZ5L211bHRpcGFydFwiLFxuICAgICAgcXM6IFwiZmFzdGlmeS1xc1wiLFxuICAgICAgc3NlOiBcImZhc3RpZnktc3NlLXYyXCIsXG4gICAgICBzdGF0aWM6IFwiQGZhc3RpZnkvc3RhdGljXCIsXG4gICAgfSBhcyBjb25zdDtcblxuICAgIGNvbnN0IHJlZ2lzdGVyUGx1Z2luID0gYXN5bmMgPEsgZXh0ZW5kcyBrZXlvZiBOb25OdWxsYWJsZTx0eXBlb2YgcGx1Z2lucz4+KFxuICAgICAga2V5OiBLLFxuICAgICAgcGx1Z2luTmFtZTogc3RyaW5nLFxuICAgICkgPT4ge1xuICAgICAgY29uc3Qgb3B0aW9uID0gcGx1Z2luc1trZXldO1xuICAgICAgaWYgKCFvcHRpb24pIHJldHVybjtcblxuICAgICAgaWYgKG9wdGlvbiA9PT0gdHJ1ZSkge1xuICAgICAgICBzZXJ2ZXIucmVnaXN0ZXIoKGF3YWl0IGltcG9ydChwbHVnaW5OYW1lKSkuZGVmYXVsdCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzZXJ2ZXIucmVnaXN0ZXIoKGF3YWl0IGltcG9ydChwbHVnaW5OYW1lKSkuZGVmYXVsdCwgb3B0aW9uKTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgZm9yIChjb25zdCBba2V5LCBwbHVnaW5OYW1lXSBvZiBPYmplY3QuZW50cmllcyhwbHVnaW5zTW9kdWxlcykpIHtcbiAgICAgIGF3YWl0IHJlZ2lzdGVyUGx1Z2luKFxuICAgICAgICAvKiBTQUZFVFk6IEFQSSDrjbDsvZTroIjsnbTthLDsmYAgWm9kIOqygOymneq4sCDrk7HroZ0g6rOE7JW97J20IOydtCDqsJLsnZgg7YOA7J6F7J2EIOuztOyepe2VnOuLpC4gKi8ga2V5IGFzIGtleW9mIHR5cGVvZiBwbHVnaW5zLFxuICAgICAgICBwbHVnaW5OYW1lLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBpZiAocGx1Z2lucy53cykge1xuICAgICAgYXdhaXQgdGhpcy5lbnN1cmVXZWJTb2NrZXRQbHVnaW4oc2VydmVyKTtcbiAgICB9XG5cbiAgICBpZiAocGx1Z2lucy5jdXN0b20pIHtcbiAgICAgIHBsdWdpbnMuY3VzdG9tKHNlcnZlcik7XG4gICAgfVxuICB9XG5cbiAgLy8gQGZhc3RpZnkvd2Vic29ja2V07J2AIHBsdWdpbnMud3PqsIAg7ISk7KCV65CcIOqyveyasOyXkOunjCDrk7HroZ3tlZjqs6AsIOqwmeydgCBzZXJ2ZXLsl5Ag7KSR67O1IOuTseuhneuQmOyngCDslYrrj4TroZ0gV2Vha1NldOycvOuhnCDquLDroZ3tlahcbiAgcHJpdmF0ZSBhc3luYyBlbnN1cmVXZWJTb2NrZXRQbHVnaW4oXG4gICAgc2VydmVyOiBGYXN0aWZ5SW5zdGFuY2U8U2VydmVyLCBJbmNvbWluZ01lc3NhZ2UsIFNlcnZlclJlc3BvbnNlPixcbiAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKHRoaXMud2Vic29ja2V0UGx1Z2luU2VydmVycy5oYXMoc2VydmVyKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHBsdWdpbk9wdGlvbiA9IHRoaXMuY29uZmlnLnNlcnZlci5wbHVnaW5zPy53cztcbiAgICBpZiAoIXBsdWdpbk9wdGlvbikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHdlYnNvY2tldFBsdWdpbiA9IChhd2FpdCBpbXBvcnQoXCJAZmFzdGlmeS93ZWJzb2NrZXRcIikpLmRlZmF1bHQ7XG4gICAgY29uc3QgcmVzb2x2ZWRQbHVnaW5PcHRpb25zID0gcmVzb2x2ZVdlYlNvY2tldFBsdWdpbk9wdGlvbnMoe1xuICAgICAgcmF3UGx1Z2luT3B0aW9uOiBwbHVnaW5PcHRpb24sXG4gICAgfSk7XG4gICAgaWYgKHJlc29sdmVkUGx1Z2luT3B0aW9ucykge1xuICAgICAgYXdhaXQgc2VydmVyLnJlZ2lzdGVyKHdlYnNvY2tldFBsdWdpbiwgcmVzb2x2ZWRQbHVnaW5PcHRpb25zKTtcbiAgICB9IGVsc2Uge1xuICAgICAgYXdhaXQgc2VydmVyLnJlZ2lzdGVyKHdlYnNvY2tldFBsdWdpbik7XG4gICAgfVxuXG4gICAgdGhpcy53ZWJzb2NrZXRQbHVnaW5TZXJ2ZXJzLmFkZChzZXJ2ZXIpO1xuICAgIHRoaXMud2Fybk9uUG90ZW50aWFsV2ViU29ja2V0VGltZW91dENvbmZsaWN0cyhzZXJ2ZXIpO1xuICB9XG5cbiAgLy8gaGVhcnRiZWF0IGludGVydmFs7J20IEZhc3RpZnkga2VlcEFsaXZlVGltZW91dCDsnbTsg4HsnbTrqbQg7J247ZSE65286rCAIOuovOyggCBpZGxlIOyXsOqysOydhCDrgYrsnYQg7IiYIOyeiOyWtCDqsr3qs6Drp4wg64Ko6riw6rOgIOuEmOyWtOqwkFxuICBwcml2YXRlIHdhcm5PblBvdGVudGlhbFdlYlNvY2tldFRpbWVvdXRDb25mbGljdHMoXG4gICAgc2VydmVyOiBGYXN0aWZ5SW5zdGFuY2U8U2VydmVyLCBJbmNvbWluZ01lc3NhZ2UsIFNlcnZlclJlc3BvbnNlPixcbiAgKTogdm9pZCB7XG4gICAgY29uc3QgaGVhcnRiZWF0cyA9IHRoaXMuc3luY2VyLmFwaXNcbiAgICAgIC5tYXAoKGFwaSkgPT4gYXBpLndlYnNvY2tldE9wdGlvbnM/LmhlYXJ0YmVhdCA/PyAzMDAwMClcbiAgICAgIC5maWx0ZXIoKGhlYXJ0YmVhdCkgPT4gaGVhcnRiZWF0ID4gMCk7XG5cbiAgICBpZiAoaGVhcnRiZWF0cy5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBrZWVwQWxpdmVUaW1lb3V0ID0gdGhpcy5jb25maWcuc2VydmVyLmZhc3RpZnk/LmtlZXBBbGl2ZVRpbWVvdXQ7XG4gICAgaWYgKCFrZWVwQWxpdmVUaW1lb3V0IHx8IGtlZXBBbGl2ZVRpbWVvdXQgPD0gMCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGxhcmdlc3RIZWFydGJlYXQgPSBNYXRoLm1heCguLi5oZWFydGJlYXRzKTtcbiAgICBpZiAobGFyZ2VzdEhlYXJ0YmVhdCA+PSBrZWVwQWxpdmVUaW1lb3V0KSB7XG4gICAgICBzZXJ2ZXIubG9nLndhcm4oXG4gICAgICAgIHtcbiAgICAgICAgICBrZWVwQWxpdmVUaW1lb3V0LFxuICAgICAgICAgIGxhcmdlc3RIZWFydGJlYXQsXG4gICAgICAgIH0sXG4gICAgICAgIFwiV2ViU29ja2V0IGhlYXJ0YmVhdCBpcyBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8ga2VlcEFsaXZlVGltZW91dDsgYWxpZ24gaW5mcmFzdHJ1Y3R1cmUgaWRsZSB0aW1lb3V0cyB0byBhdm9pZCB1bmV4cGVjdGVkIGRpc2Nvbm5lY3RzLlwiLFxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogYmV0dGVyLWF1dGgg65287Jqw7Yq466W8IOuTseuhne2VqeuLiOuLpC5cbiAgICogL2FwaS9hdXRoLyog6rK966Gc66GcIOyduOymnSBBUEnqsIAg7J6Q64+ZIOuTseuhneuQqeuLiOuLpC5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgcmVnaXN0ZXJCZXR0ZXJBdXRoKFxuICAgIHNlcnZlcjogRmFzdGlmeUluc3RhbmNlLFxuICAgIG9wdGlvbnM6IE5vbk51bGxhYmxlPFNvbmFtdVNlcnZlck9wdGlvbnNbXCJhdXRoXCJdPixcbiAgKSB7XG4gICAgaWYgKCFvcHRpb25zKSByZXR1cm47XG5cbiAgICBjb25zdCBiYXNlUGF0aCA9IG9wdGlvbnMuYmFzZVBhdGggPz8gXCIvYXBpL2F1dGhcIjtcblxuICAgIC8vIGJldHRlci1hdXRoIOudvOyasO2KuCDrk7HroZ1cbiAgICBzZXJ2ZXIucm91dGUoe1xuICAgICAgbWV0aG9kOiBbXCJHRVRcIiwgXCJQT1NUXCJdLFxuICAgICAgdXJsOiBgJHtiYXNlUGF0aH0vKmAsXG4gICAgICBoYW5kbGVyOiBhc3luYyAocmVxdWVzdCwgcmVwbHkpID0+IHtcbiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLmF1dGguaGFuZGxlcihcbiAgICAgICAgICBjcmVhdGVCZXR0ZXJBdXRoUmVxdWVzdChyZXF1ZXN0LCBvcHRpb25zLmFkdmFuY2VkPy5pcEFkZHJlc3M/LmlwQWRkcmVzc0hlYWRlcnMpLFxuICAgICAgICApO1xuXG4gICAgICAgIHJlcGx5LnN0YXR1cyhyZXNwb25zZS5zdGF0dXMpO1xuICAgICAgICByZXNwb25zZS5oZWFkZXJzLmZvckVhY2goKHZhbHVlOiBzdHJpbmcsIGtleTogc3RyaW5nKSA9PiB7XG4gICAgICAgICAgcmVwbHkuaGVhZGVyKGtleSwgdmFsdWUpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHJlcGx5LnNlbmQocmVzcG9uc2UuYm9keSA/IGF3YWl0IHJlc3BvbnNlLnRleHQoKSA6IG51bGwpO1xuICAgICAgfSxcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgcHJpbnRTdGFydHVwU3VtbWFyeSgpIHtcbiAgICBjb25zdCBhY3RpdmVQcmVzZXQgPSBnZXRTb25hbXVFbnZpcm9ubWVudCgpO1xuXG4gICAgcHJpbnREaW1TdW1tYXJ5KGBDb25maWcgbG9hZGVkJHtmb3JtYXRUaW1lKHRoaXMuY29uZmlnRWxhcHNlZCl9YCk7XG5cbiAgICAvLyBEQiBwcmVzZXQg66qp66GdXG4gICAgcHJpbnRHcmVlblN1bW1hcnkoXCJEQlwiKTtcbiAgICBjb25zdCB7IGlzTG9jYWwgfSA9IGF3YWl0IGltcG9ydChcIi4uL3V0aWxzL2NvbnRyb2xsZXJcIik7XG4gICAgY29uc3QgcHJlc2V0TmFtZXMgPVxuICAgICAgLyogU0FGRVRZOiBBUEkg642w7L2U66CI7J207YSw7JmAIFpvZCDqsoDspp3quLAg65Ox66GdIOqzhOyVveydtCDsnbQg6rCS7J2YIO2DgOyeheydhCDrs7TsnqXtlZzri6QuICovIE9iamVjdC5rZXlzKFxuICAgICAgICB0aGlzLmRiQ29uZmlnLFxuICAgICAgKSBhcyAoa2V5b2YgU29uYW11REJDb25maWcpW107XG4gICAgY29uc3QgbWF4TGVuID0gTWF0aC5tYXgoLi4ucHJlc2V0TmFtZXMubWFwKChuKSA9PiBuLmxlbmd0aCkpO1xuICAgIGZvciAoY29uc3QgbmFtZSBvZiBwcmVzZXROYW1lcykge1xuICAgICAgY29uc3QgY29ubiA9XG4gICAgICAgIC8qIFNBRkVUWTogQVBJIOuNsOy9lOugiOydtO2EsOyZgCBab2Qg6rKA7Kad6riwIOuTseuhnSDqs4Tslb3snbQg7J20IOqwkuydmCDtg4DsnoXsnYQg67O07J6l7ZWc64ukLiAqLyB0aGlzXG4gICAgICAgICAgLmRiQ29uZmlnW25hbWVdLmNvbm5lY3Rpb24gYXNcbiAgICAgICAgICB8IHsgaG9zdD86IHN0cmluZzsgcG9ydD86IG51bWJlcjsgZGF0YWJhc2U/OiBzdHJpbmcgfVxuICAgICAgICAgIHwgdW5kZWZpbmVkO1xuICAgICAgY29uc3QgaG9zdCA9IGNvbm4/Lmhvc3QgPz8gXCJsb2NhbGhvc3RcIjtcbiAgICAgIGNvbnN0IGFkZHIgPSBgQCAke2hvc3R9OiR7Y29ubj8ucG9ydCA/PyA1NDMyfS8ke2Nvbm4/LmRhdGFiYXNlID8/IFwiKHVua25vd24pXCJ9YDtcbiAgICAgIGNvbnN0IHBhZGRlZCA9IG5hbWUucGFkRW5kKG1heExlbik7XG4gICAgICBjb25zdCByZW1vdGVUYWcgPSBpc0xvY2FsKCkgJiYgIWlzTG9jYWxIb3N0KGhvc3QpID8gY2hhbGsueWVsbG93KGAgXFx1MjZhMCByZW1vdGVgKSA6IFwiXCI7XG5cbiAgICAgIGlmIChuYW1lID09PSBhY3RpdmVQcmVzZXQpIHtcbiAgICAgICAgY29uc29sZS5sb2coY2hhbGsuZ3JlZW4oYCAgXFx1MjViOCAke3BhZGRlZH0gJHthZGRyfWApICsgcmVtb3RlVGFnKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnNvbGUubG9nKGNoYWxrLmRpbShgICAgICR7cGFkZGVkfSAke2FkZHJ9YCkgKyByZW1vdGVUYWcpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0aGlzLmNvbmZpZy5zZXJ2ZXIuYXV0aCkge1xuICAgICAgY29uc3QgYmFzZVBhdGggPSB0aGlzLmNvbmZpZy5zZXJ2ZXIuYXV0aC5iYXNlUGF0aCA/PyBcIi9hcGkvYXV0aFwiO1xuICAgICAgcHJpbnREaW1TdW1tYXJ5KGBBdXRoOiBiZXR0ZXItYXV0aCBhdCAke2Jhc2VQYXRofS8qYCk7XG4gICAgfVxuICAgIGlmICh0aGlzLmNvbmZpZy5hcGkudGltZXpvbmUpIHtcbiAgICAgIHByaW50RGltU3VtbWFyeShgVGltZXpvbmU6ICR7dGhpcy5jb25maWcuYXBpLnRpbWV6b25lfWApO1xuICAgIH1cbiAgICBwcmludEdyZWVuU3VtbWFyeShgU29uYW11IHJlYWR5JHtmb3JtYXRUaW1lKHRoaXMuaW5pdEVsYXBzZWQpfWApO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBpbml0aWFsaXplQ2FjaGUoY29uZmlnOiBDYWNoZUNvbmZpZyB8IHVuZGVmaW5lZCwgZm9yVGVzdGluZzogYm9vbGVhbikge1xuICAgIGNvbnN0IHsgc2V0Q2FjaGVNYW5hZ2VyUmVmIH0gPSBhd2FpdCBpbXBvcnQoXCIuLi9jYWNoZS9kZWNvcmF0b3JcIik7XG5cbiAgICAvLyDthYzsiqTtirgg7ZmY6rK97JeQ7IScIOuplOuqqOumrCDrk5zrnbzsnbTrsoQg7J6Q64+ZIOyCrOyaqVxuICAgIGlmIChmb3JUZXN0aW5nKSB7XG4gICAgICBjb25zdCB7IGNyZWF0ZVRlc3RDYWNoZU1hbmFnZXIgfSA9IGF3YWl0IGltcG9ydChcIi4uL2NhY2hlL2NhY2hlLW1hbmFnZXJcIik7XG4gICAgICB0aGlzLmNhY2hlVmFsdWUgPSBjcmVhdGVUZXN0Q2FjaGVNYW5hZ2VyKCk7XG4gICAgICBzZXRDYWNoZU1hbmFnZXJSZWYodGhpcy5jYWNoZVZhbHVlKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyDshKTsoJXsnbQg7JeG7Jy866m0IOy6kOyLnCDruYTtmZzshLHtmZRcbiAgICBpZiAoIWNvbmZpZykge1xuICAgICAgc2V0Q2FjaGVNYW5hZ2VyUmVmKG51bGwpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIOyEpOygleyXkCDrlLDrnbwgQ2FjaGVNYW5hZ2VyIOyDneyEsVxuICAgIGNvbnN0IHsgY3JlYXRlQ2FjaGVNYW5hZ2VyIH0gPSBhd2FpdCBpbXBvcnQoXCIuLi9jYWNoZS9jYWNoZS1tYW5hZ2VyXCIpO1xuICAgIHRoaXMuY2FjaGVWYWx1ZSA9IGNyZWF0ZUNhY2hlTWFuYWdlcihjb25maWcpO1xuICAgIHNldENhY2hlTWFuYWdlclJlZih0aGlzLmNhY2hlVmFsdWUpO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBpbml0aWFsaXplV29ya2Zsb3dzKG9wdGlvbnM6IFNvbmFtdVRhc2tPcHRpb25zIHwgdW5kZWZpbmVkKSB7XG4gICAgY29uc3QgeyBXb3JrZmxvd01hbmFnZXIgfSA9IGF3YWl0IGltcG9ydChcIi4uL3Rhc2tzL3dvcmtmbG93LW1hbmFnZXJcIik7XG4gICAgLy8gTk9URTogQHNvbmFtdS1raXQvdGFza3Mg7JWI7JeQ7ISgIGtuZXggY29uZmln66W8IOyImOygle2VmOq4sCDrlYzrrLjsl5AgY29ubmVjdGlvbuydtCDslYTri4wgY29uZmlnIOynuOuhnCDrs7Trg4Xri4jri6QuXG4gICAgdGhpcy53b3JrZmxvd3NWYWx1ZSA9IG5ldyBXb3JrZmxvd01hbmFnZXIoREIuZ2V0REJDb25maWcoXCJ3XCIpKTtcbiAgICBpZiAoIW9wdGlvbnMpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBlbmFibGVXb3JrZXIgPSBvcHRpb25zLmVuYWJsZVdvcmtlciA/PyBpc0RhZW1vblNlcnZlcigpO1xuICAgIGNvbnN0IGRlZmF1bHRXb3JrZXJPcHRpb25zID0ge1xuICAgICAgY29uY3VycmVuY3k6IG9zLmNwdXMoKS5sZW5ndGggLSAxLFxuICAgICAgdXNlUHViU3ViOiB0cnVlLFxuICAgICAgbGlzdGVuRGVsYXk6IDUwMCxcbiAgICB9O1xuXG4gICAgaWYgKGVuYWJsZVdvcmtlcikge1xuICAgICAgdGhpcy53b3JrZmxvd3Muc2V0dXBXb3JrZXIoe1xuICAgICAgICAuLi5kZWZhdWx0V29ya2VyT3B0aW9ucyxcbiAgICAgICAgLi4ub3B0aW9ucy53b3JrZXJPcHRpb25zLFxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBib290KHNlcnZlcjogRmFzdGlmeUluc3RhbmNlLCBvcHRpb25zOiBTb25hbXVTZXJ2ZXJPcHRpb25zKSB7XG4gICAgY29uc3QgcG9ydCA9IG9wdGlvbnMubGlzdGVuPy5wb3J0ID8/IDMwMDA7XG4gICAgY29uc3QgaG9zdCA9IG9wdGlvbnMubGlzdGVuPy5ob3N0ID8/IFwibG9jYWxob3N0XCI7XG5cbiAgICBzZXJ2ZXIuYWRkSG9vayhcIm9uQ2xvc2VcIiwgYXN5bmMgKCkgPT4ge1xuICAgICAgYXdhaXQgb3B0aW9ucy5saWZlY3ljbGU/Lm9uU2h1dGRvd24/LihzZXJ2ZXIpO1xuICAgICAgYXdhaXQgdGhpcy53b3JrZmxvd3MuZGVzdHJveSgpO1xuICAgICAgYXdhaXQgdGhpcy5kZXN0cm95KCk7XG4gICAgfSk7XG5cbiAgICBjb25zdCBzaHV0ZG93biA9IGFzeW5jICgpID0+IHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IHNlcnZlci5jbG9zZSgpO1xuICAgICAgICBwcm9jZXNzLmV4aXQoMCk7XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgY29uc29sZS5lcnJvcihcIkVycm9yIGR1cmluZyBzaHV0ZG93bjpcIiwgZXJyKTtcbiAgICAgICAgcHJvY2Vzcy5leGl0KDEpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBwcm9jZXNzLm9uKFwiU0lHSU5UXCIsIHNodXRkb3duKTtcbiAgICBwcm9jZXNzLm9uKFwiU0lHVEVSTVwiLCBzaHV0ZG93bik7XG5cbiAgICBpZiAob3B0aW9ucy5saWZlY3ljbGU/Lm9uRXJyb3IpIHtcbiAgICAgIHNlcnZlci5zZXRFcnJvckhhbmRsZXIob3B0aW9ucy5saWZlY3ljbGU/Lm9uRXJyb3IpO1xuICAgIH1cblxuICAgIHNlcnZlclxuICAgICAgLmxpc3Rlbih7IHBvcnQsIGhvc3QgfSlcbiAgICAgIC50aGVuKGFzeW5jICgpID0+IHtcbiAgICAgICAgYXdhaXQgdGhpcy53b3JrZmxvd3Muc3RhcnRXb3JrZXIoKTtcbiAgICAgICAgYXdhaXQgb3B0aW9ucy5saWZlY3ljbGU/Lm9uU3RhcnQ/LihzZXJ2ZXIpO1xuICAgICAgfSlcbiAgICAgIC5jYXRjaChhc3luYyAoZXJyKSA9PiB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoY2hhbGsucmVkKFwiRmFpbGVkIHRvIHN0YXJ0IHNlcnZlcjpcIiwgZXJyKSk7XG4gICAgICAgIGF3YWl0IHNodXRkb3duKCk7XG4gICAgICB9KTtcbiAgfVxuXG4gIGFzeW5jIGRlc3Ryb3koKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgeyBCYXNlTW9kZWwgfSA9IGF3YWl0IGltcG9ydChcIi4uL2RhdGFiYXNlL2Jhc2UtbW9kZWxcIik7XG4gICAgLy8g66i87KCAIOyymOumrO2VtOyVvO2VqC5cbiAgICBhd2FpdCBCYXNlTW9kZWwuZGVzdHJveSgpO1xuICAgIC8vIFdlYlNvY2tldCBzaHV0ZG93biBmaXJzdCB0byBmbHVzaCB0ZWxlbWV0cnlcbiAgICBpZiAodGhpcy53ZWJzb2NrZXRSdW50aW1lVmFsdWUpIHtcbiAgICAgIGF3YWl0IHRoaXMud2Vic29ja2V0UnVudGltZVZhbHVlLnNodXRkb3duKCk7XG4gICAgfVxuICAgIHRoaXMud2Vic29ja2V0UnVudGltZVZhbHVlID0gbnVsbDtcbiAgICAvLyBUaGVuIHNodXQgZG93biByZW1haW5pbmcgcmVzb3VyY2VzIGluIHBhcmFsbGVsXG4gICAgYXdhaXQgUHJvbWlzZS5hbGxTZXR0bGVkKFtcbiAgICAgIHRoaXMud29ya2Zsb3dzVmFsdWU/LmRlc3Ryb3koKSA/PyBQcm9taXNlLnJlc29sdmUoKSxcbiAgICAgIHRoaXMuY2FjaGVWYWx1ZT8uZGlzY29ubmVjdCgpID8/IFByb21pc2UucmVzb2x2ZSgpLFxuICAgICAgdGhpcy5kZXZWaXRlc3RNYW5hZ2VyVmFsdWU/LnNodXRkb3duKCkgPz8gUHJvbWlzZS5yZXNvbHZlKCksXG4gICAgICB0aGlzLndhdGNoZXI/LmNsb3NlKCkgPz8gUHJvbWlzZS5yZXNvbHZlKCksXG4gICAgXSk7XG4gICAgLy8gTG9nVGFwZSBkaXNwb3NlIGFmdGVyIFdTIHNodXRkb3duIHNvIHRlbGVtZXRyeSByZWNvcmRzIGFyZSBmbHVzaGVkIGZpcnN0XG4gICAgYXdhaXQgbG9ndGFwZURpc3Bvc2UoKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBnZXRXZWJTb2NrZXRUZWxlbWV0cnlDb250ZXh0KFxuICB3czogQW55V2ViU29ja2V0Q29ubmVjdGlvbixcbik6IFdlYlNvY2tldFRlbGVtZXRyeUNvbm5lY3Rpb25Db250ZXh0IHtcbiAgaWYgKCFpc1RlbGVtZXRyeUNvbnRleHRQcm92aWRlcih3cykpIHtcbiAgICByZXR1cm4ge307XG4gIH1cblxuICByZXR1cm4gd3MuZ2V0VGVsZW1ldHJ5Q29udGV4dCgpO1xufVxuXG5mdW5jdGlvbiBpc1RlbGVtZXRyeUNvbnRleHRQcm92aWRlcihcbiAgd3M6IEFueVdlYlNvY2tldENvbm5lY3Rpb24sXG4pOiB3cyBpcyBBbnlXZWJTb2NrZXRDb25uZWN0aW9uICYgVGVsZW1ldHJ5Q29udGV4dFByb3ZpZGVyIHtcbiAgcmV0dXJuIFwiZ2V0VGVsZW1ldHJ5Q29udGV4dFwiIGluIHdzICYmIGlzRnVuY3Rpb25WYWx1ZSh3cy5nZXRUZWxlbWV0cnlDb250ZXh0KTtcbn1cblxuZXhwb3J0IGNvbnN0IFNvbmFtdSA9IG5ldyBTb25hbXVDbGFzcygpO1xuXG4vKipcbiAqIHN0cmVhbSDrqqjrk5zsl5DshJwg7YKkIOyDneyEsSDtlajsiJjqsIAg7KeA7KCV65CY7KeAIOyViuyVmOydhCDrlYwg7IKs7Jqp7ZWY64qUIOq4sOuzuCDtlajsiJjsnoXri4jri6QuXG4gKi9cbmZ1bmN0aW9uIGRlZmF1bHRLZXlHZW5lcmF0b3IoZmlsZTogeyBmaWxlbmFtZTogc3RyaW5nOyBtaW1ldHlwZTogc3RyaW5nIH0pOiBzdHJpbmcge1xuICBjb25zdCBleHQgPSBtaW1lLmV4dGVuc2lvbihmaWxlLm1pbWV0eXBlKSB8fCBcImJpblwiO1xuICBjb25zdCB0aW1lc3RhbXAgPSBEYXRlLm5vdygpO1xuICBjb25zdCByYW5kb20gPSBNYXRoLnJhbmRvbSgpLnRvU3RyaW5nKDM2KS5zbGljZSgyLCA4KTtcbiAgcmV0dXJuIGB1cGxvYWRzLyR7dGltZXN0YW1wfS0ke3JhbmRvbX0uJHtleHR9YDtcbn1cblxuZnVuY3Rpb24gZm9ybWF0VGltZShtczogbnVtYmVyKTogc3RyaW5nIHtcbiAgY29uc3QgZm9ybWF0dGVkID0gbXMgPj0gMTAwMCA/IGAkeyhtcyAvIDEwMDApLnRvRml4ZWQoMil9c2AgOiBgJHtNYXRoLnJvdW5kKG1zKX1tc2A7XG4gIHJldHVybiBgICgke2Zvcm1hdHRlZH0pYDtcbn1cblxuY29uc3QgTE9DQUxfSE9TVFMgPSBuZXcgU2V0KFtcImxvY2FsaG9zdFwiLCBcIjEyNy4wLjAuMVwiLCBcIjAuMC4wLjBcIiwgXCI6OjFcIl0pO1xuZnVuY3Rpb24gaXNMb2NhbEhvc3QoaG9zdDogc3RyaW5nKTogYm9vbGVhbiB7XG4gIHJldHVybiBMT0NBTF9IT1NUUy5oYXMoaG9zdCkgfHwgaG9zdC5lbmRzV2l0aChcIi5sb2NhbFwiKTtcbn1cblxuLy8gYC5ldmVyeSgpYOqwgCDssqsgZ3VhcmQg7J207ZuEIOyInO2ajOulvCDrqYjstpTripQg66y47KCc6rCAIOyeiOyWtCBgZm9yLi4ub2Zg66GcIOuqqOuToCBndWFyZOulvCDsiJzshJzrjIDroZwg7Iuk7ZaJ7ZWY64+E66GdIOqzoOygle2VqFxuZnVuY3Rpb24gcnVuR3VhcmRzKHtcbiAgZ3VhcmRzLFxuICBjb25maWcsXG4gIHJlcXVlc3QsXG4gIGFwaSxcbn06IHtcbiAgZ3VhcmRzOiBFeHRlbmRlZEFwaVtcIm9wdGlvbnNcIl1bXCJndWFyZHNcIl0gfCB1bmRlZmluZWQ7XG4gIGNvbmZpZzogUGljazxTb25hbXVGYXN0aWZ5Q29uZmlnLCBcImd1YXJkSGFuZGxlclwiPjtcbiAgcmVxdWVzdDogRmFzdGlmeVJlcXVlc3Q7XG4gIGFwaTogRXh0ZW5kZWRBcGk7XG59KTogdm9pZCB7XG4gIGZvciAoY29uc3QgZ3VhcmQgb2YgZ3VhcmRzID8/IFtdKSB7XG4gICAgY29uZmlnLmd1YXJkSGFuZGxlcihndWFyZCwgcmVxdWVzdCwgYXBpKTtcbiAgfVxufVxuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQTZHQSxTQUFTLGNBQXFCLE9BQTJCO0NBQ3ZELElBQUksVUFBVSxNQUFNLE9BQU87Q0FDM0IsSUFBSSxVQUFVLFFBQVcsT0FBTztDQUNoQyxJQUFJLFVBQVUsTUFBTSxPQUFPO0NBQzNCLElBQUksVUFBVSxPQUFPLE9BQU87Q0FDNUIsSUFBSSxjQUFjLEtBQUssR0FBRyxPQUFPO0NBQ2pDLElBQUksY0FBYyxLQUFLLEdBQUcsT0FBTztDQUNqQyxJQUFJLGNBQWMsS0FBSyxHQUFHLE9BQU87Q0FDakMsSUFBSSxjQUFjLEtBQUssR0FBRyxPQUFPO0NBQ2pDLElBQUksZ0JBQWdCLEtBQUssR0FBRyxPQUFPO0NBQ25DLElBQUksY0FBYyxL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
|