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
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import { __esmMin } from "../_virtual/_rolldown/runtime.js";
|
|
2
2
|
import { createKnexInstance, init_knex } from "../database/knex.js";
|
|
3
3
|
import { init_controller, isTest } from "../utils/controller.js";
|
|
4
|
-
import { Sonamu, init_sonamu } from "../api/sonamu.js";
|
|
5
4
|
import { init_types, isBelongsToOneRelationProp, isHasManyRelationProp, isManyToManyRelationProp, isOneToOneRelationProp, isRelationProp, isVirtualProp } from "../types/types.js";
|
|
5
|
+
import { Sonamu, init_sonamu } from "../api/sonamu.js";
|
|
6
6
|
import { EntityManager, init_entity_manager } from "../entity/entity-manager.js";
|
|
7
7
|
import { UpsertBuilder, init_upsert_builder } from "../database/upsert-builder.js";
|
|
8
8
|
import { BaseModel, init_base_model } from "../database/base-model.js";
|
|
9
9
|
import { RelationGraph, init__relation_graph } from "./_relation-graph.js";
|
|
10
|
+
import { dataExplorerRecordSchema, init_data_explorer } from "./data-explorer.js";
|
|
10
11
|
import inflection from "inflection";
|
|
12
|
+
import { z } from "zod";
|
|
11
13
|
import { unique } from "radashi";
|
|
12
14
|
import assert from "assert";
|
|
13
15
|
import { readFileSync, writeFileSync } from "fs";
|
|
@@ -15,7 +17,14 @@ import chalk from "chalk";
|
|
|
15
17
|
import { execSync } from "child_process";
|
|
16
18
|
import { inspect } from "util";
|
|
17
19
|
//#region src/testing/fixture-manager.ts
|
|
18
|
-
|
|
20
|
+
function executeFixtureSyncCommand(command, options) {
|
|
21
|
+
try {
|
|
22
|
+
execSync(command, options);
|
|
23
|
+
} catch (error) {
|
|
24
|
+
throw new Error("Fixture database synchronization command failed", { cause: error });
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
var pgConnectionSchema, databaseConnectionSchema, fixtureRecordIdsSchema, relationIdSchema, FixtureManagerClass, FixtureManager;
|
|
19
28
|
var init_fixture_manager = __esmMin((() => {
|
|
20
29
|
init_sonamu();
|
|
21
30
|
init_base_model();
|
|
@@ -25,22 +34,37 @@ var init_fixture_manager = __esmMin((() => {
|
|
|
25
34
|
init_types();
|
|
26
35
|
init_controller();
|
|
27
36
|
init__relation_graph();
|
|
37
|
+
init_data_explorer();
|
|
38
|
+
pgConnectionSchema = z.object({
|
|
39
|
+
host: z.string().optional(),
|
|
40
|
+
port: z.number().optional(),
|
|
41
|
+
user: z.string().optional(),
|
|
42
|
+
password: z.string().optional(),
|
|
43
|
+
database: z.string()
|
|
44
|
+
}).passthrough();
|
|
45
|
+
databaseConnectionSchema = z.object({ database: z.string() }).passthrough();
|
|
46
|
+
fixtureRecordIdsSchema = z.array(z.union([z.number(), z.string()]));
|
|
47
|
+
relationIdSchema = z.union([
|
|
48
|
+
z.number(),
|
|
49
|
+
z.string(),
|
|
50
|
+
z.null()
|
|
51
|
+
]);
|
|
28
52
|
FixtureManagerClass = class {
|
|
29
|
-
|
|
53
|
+
testingDb = null;
|
|
30
54
|
set tdb(tdb) {
|
|
31
|
-
this.
|
|
55
|
+
this.testingDb = tdb;
|
|
32
56
|
}
|
|
33
57
|
get tdb() {
|
|
34
|
-
if (this.
|
|
35
|
-
return this.
|
|
58
|
+
if (this.testingDb === null) throw new Error("FixtureManager has not been initialized");
|
|
59
|
+
return this.testingDb;
|
|
36
60
|
}
|
|
37
|
-
|
|
61
|
+
fixtureDb = null;
|
|
38
62
|
set fdb(fdb) {
|
|
39
|
-
this.
|
|
63
|
+
this.fixtureDb = fdb;
|
|
40
64
|
}
|
|
41
65
|
get fdb() {
|
|
42
|
-
if (this.
|
|
43
|
-
return this.
|
|
66
|
+
if (this.fixtureDb === null) throw new Error("FixtureManager has not been initialized");
|
|
67
|
+
return this.fixtureDb;
|
|
44
68
|
}
|
|
45
69
|
cachedTableNames = null;
|
|
46
70
|
relationGraph = new RelationGraph();
|
|
@@ -48,10 +72,10 @@ var init_fixture_manager = __esmMin((() => {
|
|
|
48
72
|
fixtureRefMap = /* @__PURE__ */ new Map();
|
|
49
73
|
skippedFixtures = /* @__PURE__ */ new Map();
|
|
50
74
|
init() {
|
|
51
|
-
if (this.
|
|
75
|
+
if (this.testingDb !== null) return;
|
|
52
76
|
if (Sonamu.dbConfig.test && Sonamu.dbConfig.production) {
|
|
53
|
-
const tConn = Sonamu.dbConfig.test.connection;
|
|
54
|
-
const pConn = Sonamu.dbConfig.production.connection;
|
|
77
|
+
const tConn = pgConnectionSchema.parse(Sonamu.dbConfig.test.connection);
|
|
78
|
+
const pConn = pgConnectionSchema.parse(Sonamu.dbConfig.production.connection);
|
|
55
79
|
if (`${tConn.host ?? "localhost"}:${tConn.port ?? 5432}/${tConn.database}` === `${pConn.host ?? "localhost"}:${pConn.port ?? 5432}/${pConn.database}`) throw new Error(`테스트DB와 프로덕션DB에 동일한 데이터베이스가 사용되었습니다.`);
|
|
56
80
|
}
|
|
57
81
|
this.tdb = createKnexInstance(Sonamu.dbConfig.test);
|
|
@@ -62,10 +86,10 @@ var init_fixture_manager = __esmMin((() => {
|
|
|
62
86
|
pg_dump로 원격 DB를 덤프하고, pg_restore로 로컬에 복원합니다.
|
|
63
87
|
*/
|
|
64
88
|
async sync() {
|
|
65
|
-
const fixtureConn = Sonamu.dbConfig.fixture.connection;
|
|
66
|
-
const testConn = Sonamu.dbConfig.test.connection;
|
|
89
|
+
const fixtureConn = pgConnectionSchema.parse(Sonamu.dbConfig.fixture.connection);
|
|
90
|
+
const testConn = pgConnectionSchema.parse(Sonamu.dbConfig.test.connection);
|
|
67
91
|
const testPgEnv = { PGPASSWORD: testConn.password || "" };
|
|
68
|
-
|
|
92
|
+
executeFixtureSyncCommand(`psql -h ${testConn.host} -p ${testConn.port ?? 5432} -U ${testConn.user} -d postgres -c "
|
|
69
93
|
SELECT pg_terminate_backend(pg_stat_activity.pid)
|
|
70
94
|
FROM pg_stat_activity
|
|
71
95
|
WHERE datname = '${testConn.database}'
|
|
@@ -77,14 +101,14 @@ var init_fixture_manager = __esmMin((() => {
|
|
|
77
101
|
...testPgEnv
|
|
78
102
|
}
|
|
79
103
|
});
|
|
80
|
-
|
|
104
|
+
executeFixtureSyncCommand(`psql -h ${testConn.host} -p ${testConn.port ?? 5432} -U ${testConn.user} -d postgres -c "DROP DATABASE IF EXISTS \\"${testConn.database}\\""`, {
|
|
81
105
|
stdio: "inherit",
|
|
82
106
|
env: {
|
|
83
107
|
...process.env,
|
|
84
108
|
...testPgEnv
|
|
85
109
|
}
|
|
86
110
|
});
|
|
87
|
-
|
|
111
|
+
executeFixtureSyncCommand(`psql -h ${testConn.host} -p ${testConn.port ?? 5432} -U ${testConn.user} -d postgres -c "CREATE DATABASE \\"${testConn.database}\\""`, {
|
|
88
112
|
stdio: "inherit",
|
|
89
113
|
env: {
|
|
90
114
|
...process.env,
|
|
@@ -94,7 +118,7 @@ var init_fixture_manager = __esmMin((() => {
|
|
|
94
118
|
const fixturePgEnv = { PGPASSWORD: fixtureConn.password || "" };
|
|
95
119
|
const dumpCmd = `pg_dump -h ${fixtureConn.host} -p ${fixtureConn.port ?? 5432} -U ${fixtureConn.user} -d ${fixtureConn.database} -Fc`;
|
|
96
120
|
const restoreCmd = `pg_restore -h ${testConn.host} -p ${testConn.port ?? 5432} -U ${testConn.user} -d ${testConn.database} --no-owner --no-acl`;
|
|
97
|
-
|
|
121
|
+
executeFixtureSyncCommand(`${dumpCmd} | PGPASSWORD="${testConn.password || ""}" ${restoreCmd}`, {
|
|
98
122
|
stdio: "inherit",
|
|
99
123
|
env: {
|
|
100
124
|
...process.env,
|
|
@@ -148,40 +172,40 @@ var init_fixture_manager = __esmMin((() => {
|
|
|
148
172
|
const entity = EntityManager.get(entityId);
|
|
149
173
|
const [row] = await BaseModel.getDB("w")(entity.table).where(field, id).limit(1);
|
|
150
174
|
if (row === void 0) throw new Error(`${entityId}#${id} row를 찾을 수 없습니다.`);
|
|
151
|
-
const fixtureDatabase = Sonamu.dbConfig.fixture.connection.database;
|
|
152
|
-
const realDatabase = Sonamu.dbConfig.production.connection.database;
|
|
175
|
+
const fixtureDatabase = databaseConnectionSchema.parse(Sonamu.dbConfig.fixture.connection).database;
|
|
176
|
+
const realDatabase = databaseConnectionSchema.parse(Sonamu.dbConfig.production.connection).database;
|
|
153
177
|
const selfQuery = `INSERT IGNORE INTO \`${fixtureDatabase}\`.\`${entity.table}\` (SELECT * FROM \`${realDatabase}\`.\`${entity.table}\` WHERE \`id\` = ${id})`;
|
|
154
178
|
const args = Object.entries(entity.relations).filter(([, relation]) => isBelongsToOneRelationProp(relation) || isOneToOneRelationProp(relation) && relation.customJoinClause === void 0).map(([, relation]) => {
|
|
155
|
-
let
|
|
156
|
-
let
|
|
179
|
+
let relationField;
|
|
180
|
+
let relationId;
|
|
157
181
|
if (isOneToOneRelationProp(relation) && !relation.hasJoinColumn) {
|
|
158
182
|
const relatedEntity = EntityManager.get(relation.with);
|
|
159
183
|
const relatedIdColumnName = relatedEntity.props.find((p) => isRelationProp(p) && p.with === entity.id)?.name;
|
|
160
184
|
if (!relatedIdColumnName) throw new Error(`${relatedEntity.id}의 ${entity.id} 관계 프롭을 찾을 수 없습니다.`);
|
|
161
|
-
|
|
162
|
-
|
|
185
|
+
relationField = `${relatedIdColumnName}_id`;
|
|
186
|
+
relationId = row.id;
|
|
163
187
|
} else {
|
|
164
|
-
|
|
165
|
-
|
|
188
|
+
relationField = "id";
|
|
189
|
+
relationId = row[`${relation.name}_id`];
|
|
166
190
|
}
|
|
167
191
|
return {
|
|
168
192
|
entityId: relation.with,
|
|
169
|
-
field,
|
|
170
|
-
id
|
|
193
|
+
field: relationField,
|
|
194
|
+
id: relationId
|
|
171
195
|
};
|
|
172
196
|
}).filter((arg) => arg.id !== null);
|
|
173
|
-
return [...unique((await Promise.all(args.map(async (
|
|
174
|
-
return this.getImportQueries(
|
|
197
|
+
return [...unique((await Promise.all(args.map(async (relationArgs) => {
|
|
198
|
+
return this.getImportQueries(relationArgs.entityId, relationArgs.field, relationArgs.id);
|
|
175
199
|
}))).toReversed().flat()), selfQuery];
|
|
176
200
|
}
|
|
177
201
|
async destroy() {
|
|
178
|
-
if (this.
|
|
179
|
-
await this.
|
|
180
|
-
this.
|
|
202
|
+
if (this.testingDb) {
|
|
203
|
+
await this.testingDb.destroy();
|
|
204
|
+
this.testingDb = null;
|
|
181
205
|
}
|
|
182
|
-
if (this.
|
|
183
|
-
await this.
|
|
184
|
-
this.
|
|
206
|
+
if (this.fixtureDb) {
|
|
207
|
+
await this.fixtureDb.destroy();
|
|
208
|
+
this.fixtureDb = null;
|
|
185
209
|
}
|
|
186
210
|
await BaseModel.destroy();
|
|
187
211
|
}
|
|
@@ -200,29 +224,29 @@ var init_fixture_manager = __esmMin((() => {
|
|
|
200
224
|
const fixtures = [];
|
|
201
225
|
for (const row of rows) {
|
|
202
226
|
const initialRecordsLength = fixtures.length;
|
|
203
|
-
const newRecords = await this.createFixtureRecord(entity, row, {
|
|
227
|
+
const newRecords = await this.createFixtureRecord(entity, row, { db: sourceDB });
|
|
204
228
|
fixtures.push(...newRecords);
|
|
205
229
|
const currentFixtureRecord = fixtures.find((r) => r.fixtureId === `${entityId}#${row.id}`);
|
|
206
230
|
if (currentFixtureRecord) currentFixtureRecord.fetchedRecords = fixtures.filter((r) => r.fixtureId !== currentFixtureRecord.fixtureId).slice(initialRecordsLength).map((r) => r.fixtureId);
|
|
207
231
|
}
|
|
208
232
|
for (const fixture of fixtures) {
|
|
209
|
-
const
|
|
233
|
+
const fixtureEntity = EntityManager.get(fixture.entityId);
|
|
210
234
|
const customColumns = duplicateCheck?.columns?.[fixture.entityId];
|
|
211
235
|
if (customColumns && customColumns.length > 0) {
|
|
212
|
-
const customDuplicateRow = await this.checkDuplicateByColumns(targetDB,
|
|
236
|
+
const customDuplicateRow = await this.checkDuplicateByColumns(targetDB, fixtureEntity, fixture, customColumns);
|
|
213
237
|
if (customDuplicateRow) {
|
|
214
|
-
const [record] = await this.createFixtureRecord(
|
|
238
|
+
const [record] = await this.createFixtureRecord(fixtureEntity, customDuplicateRow, {
|
|
215
239
|
singleRecord: true,
|
|
216
|
-
|
|
240
|
+
db: targetDB
|
|
217
241
|
});
|
|
218
242
|
fixture.target = record;
|
|
219
243
|
}
|
|
220
244
|
}
|
|
221
|
-
const uniqueRow = await this.checkUniqueViolation(targetDB,
|
|
245
|
+
const uniqueRow = await this.checkUniqueViolation(targetDB, fixtureEntity, fixture);
|
|
222
246
|
if (uniqueRow) {
|
|
223
|
-
const [record] = await this.createFixtureRecord(
|
|
247
|
+
const [record] = await this.createFixtureRecord(fixtureEntity, uniqueRow, {
|
|
224
248
|
singleRecord: true,
|
|
225
|
-
|
|
249
|
+
db: targetDB
|
|
226
250
|
});
|
|
227
251
|
fixture.unique = record;
|
|
228
252
|
}
|
|
@@ -232,7 +256,7 @@ var init_fixture_manager = __esmMin((() => {
|
|
|
232
256
|
await Promise.allSettled([targetDB.destroy(), sourceDB.destroy()]);
|
|
233
257
|
}
|
|
234
258
|
}
|
|
235
|
-
async createFixtureRecord(
|
|
259
|
+
async createFixtureRecord(rootEntity, rootRow, options) {
|
|
236
260
|
const records = [];
|
|
237
261
|
const visitedEntities = /* @__PURE__ */ new Set();
|
|
238
262
|
const create = async (entity, row) => {
|
|
@@ -249,11 +273,12 @@ var init_fixture_manager = __esmMin((() => {
|
|
|
249
273
|
};
|
|
250
274
|
for (const prop of entity.props) {
|
|
251
275
|
if (isVirtualProp(prop)) continue;
|
|
276
|
+
const columnValue = row[prop.name];
|
|
252
277
|
record.columns[prop.name] = {
|
|
253
278
|
prop,
|
|
254
|
-
value:
|
|
279
|
+
value: columnValue
|
|
255
280
|
};
|
|
256
|
-
const db = options?.
|
|
281
|
+
const db = options?.db ?? BaseModel.getDB("w");
|
|
257
282
|
if (isManyToManyRelationProp(prop)) {
|
|
258
283
|
const relatedEntity = EntityManager.get(prop.with);
|
|
259
284
|
const throughTable = prop.joinTable;
|
|
@@ -273,19 +298,22 @@ var init_fixture_manager = __esmMin((() => {
|
|
|
273
298
|
record.columns[prop.name].value = relatedRow?.id;
|
|
274
299
|
}
|
|
275
300
|
} else if (isRelationProp(prop)) {
|
|
276
|
-
const relatedId = row[`${prop.name}_id`];
|
|
301
|
+
const relatedId = relationIdSchema.parse(row[`${prop.name}_id`]);
|
|
277
302
|
record.columns[prop.name].value = relatedId;
|
|
278
303
|
if (relatedId) record.belongsRecords.push(`${prop.with}#${relatedId}`);
|
|
279
304
|
if (!options?.singleRecord && relatedId) {
|
|
280
305
|
const relatedEntity = EntityManager.get(prop.with);
|
|
281
306
|
const relatedRow = await db(relatedEntity.table).where("id", relatedId).first();
|
|
282
|
-
if (relatedRow) await create(relatedEntity,
|
|
307
|
+
if (relatedRow) await create(relatedEntity, {
|
|
308
|
+
...dataExplorerRecordSchema.parse(relatedRow),
|
|
309
|
+
id: z.union([z.number(), z.string()]).parse(relatedRow.id)
|
|
310
|
+
});
|
|
283
311
|
}
|
|
284
312
|
}
|
|
285
313
|
}
|
|
286
314
|
records.push(record);
|
|
287
315
|
};
|
|
288
|
-
await create(
|
|
316
|
+
await create(rootEntity, rootRow);
|
|
289
317
|
return records;
|
|
290
318
|
}
|
|
291
319
|
/**
|
|
@@ -306,7 +334,7 @@ var init_fixture_manager = __esmMin((() => {
|
|
|
306
334
|
const db = createKnexInstance(process.env.SONAMU_WORKER_DB === "true" && process.env.VITEST_POOL_ID ? (() => {
|
|
307
335
|
const workerId = parseInt(process.env.VITEST_POOL_ID ?? "1", 10);
|
|
308
336
|
const baseConfig = Sonamu.dbConfig[dbName];
|
|
309
|
-
const connection = baseConfig.connection;
|
|
337
|
+
const connection = databaseConnectionSchema.parse(baseConfig.connection);
|
|
310
338
|
return {
|
|
311
339
|
...baseConfig,
|
|
312
340
|
connection: {
|
|
@@ -361,9 +389,10 @@ var init_fixture_manager = __esmMin((() => {
|
|
|
361
389
|
this.registerFixture(fixture, insertedIdsByTable);
|
|
362
390
|
!isTest() && console.log(chalk.blue(`Registered ${fixture.entityId}#${fixture.id}${fixture.override ? ` (override)` : ""}`));
|
|
363
391
|
}
|
|
364
|
-
const uuids = this.builder.getTable(tableName).rows.map((row) => row.uuid);
|
|
392
|
+
const uuids = this.builder.getTable(tableName).rows.map((row) => z.string().parse(row.uuid));
|
|
365
393
|
!isTest() && console.log(chalk.blue(`Upserting ${tableName} with ${uuids.length} rows (level ${levels.indexOf(levelFixtures) + 1}/${levels.length})`));
|
|
366
|
-
const
|
|
394
|
+
const schemaTableName = tableName;
|
|
395
|
+
const ids = fixtureRecordIdsSchema.parse(await this.builder.upsert(trx, schemaTableName));
|
|
367
396
|
if (uuids.length > 0 && uuids.length === ids.length) {
|
|
368
397
|
const existingMap = insertedIdsByTable.get(tableName) ?? /* @__PURE__ */ new Map();
|
|
369
398
|
for (let i = 0; i < uuids.length; i++) existingMap.set(uuids[i], ids[i]);
|
|
@@ -441,7 +470,7 @@ var init_fixture_manager = __esmMin((() => {
|
|
|
441
470
|
}
|
|
442
471
|
if (isRelationProp(prop)) {
|
|
443
472
|
if (isBelongsToOneRelationProp(prop) || isOneToOneRelationProp(prop) && prop.hasJoinColumn) {
|
|
444
|
-
const relatedId = column.value;
|
|
473
|
+
const relatedId = relationIdSchema.parse(column.value);
|
|
445
474
|
if (relatedId !== null && relatedId !== void 0) {
|
|
446
475
|
const relatedFixtureId = `${prop.with}#${relatedId}`;
|
|
447
476
|
const skippedExistingId = this.skippedFixtures.get(relatedFixtureId)?.existingId;
|
|
@@ -472,7 +501,10 @@ var init_fixture_manager = __esmMin((() => {
|
|
|
472
501
|
switch (prop.type) {
|
|
473
502
|
case "json": return value;
|
|
474
503
|
case "date":
|
|
475
|
-
|
|
504
|
+
{
|
|
505
|
+
const dateSource = z.union([z.string(), z.number()]).safeParse(value);
|
|
506
|
+
if (dateSource.success) return new Date(dateSource.data);
|
|
507
|
+
}
|
|
476
508
|
return value;
|
|
477
509
|
default: return value;
|
|
478
510
|
}
|
|
@@ -489,7 +521,7 @@ var init_fixture_manager = __esmMin((() => {
|
|
|
489
521
|
if (isManyToManyRelationProp(prop) && Array.isArray(column.value)) {
|
|
490
522
|
const targetTable = EntityManager.get(prop.with);
|
|
491
523
|
if (!this.builder.hasTable(targetTable.table)) continue;
|
|
492
|
-
const relatedIds = column.value;
|
|
524
|
+
const relatedIds = fixtureRecordIdsSchema.parse(column.value);
|
|
493
525
|
if (relatedIds.length === 0) continue;
|
|
494
526
|
const joinTable = prop.joinTable;
|
|
495
527
|
const relatedEntity = EntityManager.get(prop.with);
|
|
@@ -546,7 +578,7 @@ var init_fixture_manager = __esmMin((() => {
|
|
|
546
578
|
for (const fixture of fixtures) {
|
|
547
579
|
if (!remaining.has(fixture.fixtureId)) continue;
|
|
548
580
|
if (selfRefProps.every((prop) => {
|
|
549
|
-
const refId = fixture.columns[prop.name]?.value;
|
|
581
|
+
const refId = relationIdSchema.parse(fixture.columns[prop.name]?.value);
|
|
550
582
|
if (refId === null || refId === void 0) return true;
|
|
551
583
|
const refFixtureId = `${prop.with}#${refId}`;
|
|
552
584
|
return processed.has(refFixtureId) || !remaining.has(refFixtureId);
|
|
@@ -615,4 +647,4 @@ var init_fixture_manager = __esmMin((() => {
|
|
|
615
647
|
init_fixture_manager();
|
|
616
648
|
export { FixtureManager, FixtureManagerClass, init_fixture_manager };
|
|
617
649
|
|
|
618
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZml4dHVyZS1tYW5hZ2VyLmpzIiwibmFtZXMiOltdLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy90ZXN0aW5nL2ZpeHR1cmUtbWFuYWdlci50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgYXNzZXJ0IGZyb20gXCJhc3NlcnRcIjtcbmltcG9ydCB7IGV4ZWNTeW5jIH0gZnJvbSBcImNoaWxkX3Byb2Nlc3NcIjtcbmltcG9ydCB7IHJlYWRGaWxlU3luYywgd3JpdGVGaWxlU3luYyB9IGZyb20gXCJmc1wiO1xuaW1wb3J0IHsgaW5zcGVjdCB9IGZyb20gXCJ1dGlsXCI7XG5cbmltcG9ydCBjaGFsayBmcm9tIFwiY2hhbGtcIjtcbmltcG9ydCBpbmZsZWN0aW9uIGZyb20gXCJpbmZsZWN0aW9uXCI7XG5pbXBvcnQgeyB0eXBlIEtuZXggfSBmcm9tIFwia25leFwiO1xuaW1wb3J0IHsgdW5pcXVlIH0gZnJvbSBcInJhZGFzaGlcIjtcblxuaW1wb3J0IHsgU29uYW11IH0gZnJvbSBcIi4uL2FwaS9zb25hbXVcIjtcbmltcG9ydCB7IEJhc2VNb2RlbCB9IGZyb20gXCIuLi9kYXRhYmFzZS9iYXNlLW1vZGVsXCI7XG5pbXBvcnQgeyB0eXBlIFNvbmFtdURCQ29uZmlnIH0gZnJvbSBcIi4uL2RhdGFiYXNlL2RiXCI7XG5pbXBvcnQgeyBjcmVhdGVLbmV4SW5zdGFuY2UgfSBmcm9tIFwiLi4vZGF0YWJhc2Uva25leFwiO1xuaW1wb3J0IHsgVXBzZXJ0QnVpbGRlciB9IGZyb20gXCIuLi9kYXRhYmFzZS91cHNlcnQtYnVpbGRlclwiO1xuaW1wb3J0IHsgdHlwZSBVQlJlZiB9IGZyb20gXCIuLi9kYXRhYmFzZS91cHNlcnQtYnVpbGRlclwiO1xuaW1wb3J0IHsgdHlwZSBFbnRpdHkgfSBmcm9tIFwiLi4vZW50aXR5L2VudGl0eVwiO1xuaW1wb3J0IHsgRW50aXR5TWFuYWdlciB9IGZyb20gXCIuLi9lbnRpdHkvZW50aXR5LW1hbmFnZXJcIjtcbmltcG9ydCB7XG4gIGlzQmVsb25nc1RvT25lUmVsYXRpb25Qcm9wLFxuICBpc0hhc01hbnlSZWxhdGlvblByb3AsXG4gIGlzTWFueVRvTWFueVJlbGF0aW9uUHJvcCxcbiAgaXNPbmVUb09uZVJlbGF0aW9uUHJvcCxcbiAgaXNSZWxhdGlvblByb3AsXG4gIGlzVmlydHVhbFByb3AsXG59IGZyb20gXCIuLi90eXBlcy90eXBlc1wiO1xuaW1wb3J0IHtcbiAgdHlwZSBCZWxvbmdzVG9PbmVSZWxhdGlvblByb3AsXG4gIHR5cGUgRGF0YWJhc2VTY2hlbWFFeHRlbmQsXG4gIHR5cGUgRW50aXR5UHJvcCxcbiAgdHlwZSBGaXh0dXJlSW1wb3J0UmVzdWx0LFxuICB0eXBlIEZpeHR1cmVSZWNvcmQsXG4gIHR5cGUgRml4dHVyZVNlYXJjaE9wdGlvbnMsXG4gIHR5cGUgT25lVG9PbmVSZWxhdGlvblByb3AsXG59IGZyb20gXCIuLi90eXBlcy90eXBlc1wiO1xuaW1wb3J0IHsgaXNUZXN0IH0gZnJvbSBcIi4uL3V0aWxzL2NvbnRyb2xsZXJcIjtcbmltcG9ydCB7IFJlbGF0aW9uR3JhcGggfSBmcm9tIFwiLi9fcmVsYXRpb24tZ3JhcGhcIjtcblxuLyoqIOyCrOyaqeyekCDsp4DsoJUg7KSR67O1IO2ZleyduCDsu6zrn7wgKGVudGl0eUlk67OE66GcIOyngOyglSkgKi9cbmV4cG9ydCBpbnRlcmZhY2UgRHVwbGljYXRlQ2hlY2tPcHRpb25zIHtcbiAgY29sdW1ucz86IHtcbiAgICBbZW50aXR5SWQ6IHN0cmluZ106IHN0cmluZ1tdO1xuICB9O1xufVxuXG5leHBvcnQgY2xhc3MgRml4dHVyZU1hbmFnZXJDbGFzcyB7XG4gIHByaXZhdGUgX3RkYjogS25leCB8IG51bGwgPSBudWxsO1xuICBzZXQgdGRiKHRkYjogS25leCkge1xuICAgIHRoaXMuX3RkYiA9IHRkYjtcbiAgfVxuICBnZXQgdGRiKCk6IEtuZXgge1xuICAgIGlmICh0aGlzLl90ZGIgPT09IG51bGwpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkZpeHR1cmVNYW5hZ2VyIGhhcyBub3QgYmVlbiBpbml0aWFsaXplZFwiKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX3RkYjtcbiAgfVxuXG4gIHByaXZhdGUgX2ZkYjogS25leCB8IG51bGwgPSBudWxsO1xuICBzZXQgZmRiKGZkYjogS25leCkge1xuICAgIHRoaXMuX2ZkYiA9IGZkYjtcbiAgfVxuICBnZXQgZmRiKCk6IEtuZXgge1xuICAgIGlmICh0aGlzLl9mZGIgPT09IG51bGwpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkZpeHR1cmVNYW5hZ2VyIGhhcyBub3QgYmVlbiBpbml0aWFsaXplZFwiKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX2ZkYjtcbiAgfVxuICBjYWNoZWRUYWJsZU5hbWVzOiBzdHJpbmdbXSB8IG51bGwgPSBudWxsO1xuXG4gIHByaXZhdGUgcmVsYXRpb25HcmFwaCA9IG5ldyBSZWxhdGlvbkdyYXBoKCk7XG5cbiAgLy8gVXBzZXJ0QnVpbGRlciDquLDrsJggaW1wb3J066W8IOychO2VnCDsg4Htg5xcbiAgcHJpdmF0ZSBidWlsZGVyOiBVcHNlcnRCdWlsZGVyID0gbmV3IFVwc2VydEJ1aWxkZXIoKTtcbiAgcHJpdmF0ZSBmaXh0dXJlUmVmTWFwOiBNYXA8c3RyaW5nLCBVQlJlZj4gPSBuZXcgTWFwKCk7XG4gIHByaXZhdGUgc2tpcHBlZEZpeHR1cmVzOiBNYXA8c3RyaW5nLCB7IGVudGl0eUlkOiBzdHJpbmc7IGV4aXN0aW5nSWQ6IG51bWJlciB8IHN0cmluZyB9PiA9XG4gICAgbmV3IE1hcCgpO1xuXG4gIGluaXQoKSB7XG4gICAgaWYgKHRoaXMuX3RkYiAhPT0gbnVsbCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoU29uYW11LmRiQ29uZmlnLnRlc3QgJiYgU29uYW11LmRiQ29uZmlnLnByb2R1Y3Rpb24pIHtcbiAgICAgIGNvbnN0IHRDb25uID0gU29uYW11LmRiQ29uZmlnLnRlc3QuY29ubmVjdGlvbiBhcyBLbmV4LkNvbm5lY3Rpb25Db25maWcgJiB7XG4gICAgICAgIHBvcnQ/OiBudW1iZXI7XG4gICAgICB9O1xuICAgICAgY29uc3QgcENvbm4gPSBTb25hbXUuZGJDb25maWcucHJvZHVjdGlvbi5jb25uZWN0aW9uIGFzIEtuZXguQ29ubmVjdGlvbkNvbmZpZyAmIHtcbiAgICAgICAgcG9ydD86IG51bWJlcjtcbiAgICAgIH07XG4gICAgICBpZiAoXG4gICAgICAgIGAke3RDb25uLmhvc3QgPz8gXCJsb2NhbGhvc3RcIn06JHt0Q29ubi5wb3J0ID8/IDU0MzJ9LyR7dENvbm4uZGF0YWJhc2V9YCA9PT1cbiAgICAgICAgYCR7cENvbm4uaG9zdCA/PyBcImxvY2FsaG9zdFwifToke3BDb25uLnBvcnQgPz8gNTQzMn0vJHtwQ29ubi5kYXRhYmFzZX1gXG4gICAgICApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGDthYzsiqTtirhEQuyZgCDtlITroZzrjZXshZhEQuyXkCDrj5nsnbztlZwg642w7J207YSw67Kg7J207Iqk6rCAIOyCrOyaqeuQmOyXiOyKteuLiOuLpC5gKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLnRkYiA9IGNyZWF0ZUtuZXhJbnN0YW5jZShTb25hbXUuZGJDb25maWcudGVzdCk7XG4gICAgdGhpcy5mZGIgPSBjcmVhdGVLbmV4SW5zdGFuY2UoU29uYW11LmRiQ29uZmlnLmZpeHR1cmUpO1xuICB9XG5cbiAgLyoqXG4gICAg7JuQ6rKpIGZpeHR1cmUgRELrpbwg66Gc7LusIHRlc3QgRELroZwg67O17IKs7ZWp64uI64ukLlxuICAgIHBnX2R1bXDroZwg7JuQ6rKpIERC66W8IOuNpO2UhO2VmOqzoCwgcGdfcmVzdG9yZeuhnCDroZzsu6zsl5Ag67O17JuQ7ZWp64uI64ukLlxuICAqL1xuICBhc3luYyBzeW5jKCkge1xuICAgIGNvbnN0IGZpeHR1cmVDb25uID0gU29uYW11LmRiQ29uZmlnLmZpeHR1cmUuY29ubmVjdGlvbiBhcyBLbmV4LlBnQ29ubmVjdGlvbkNvbmZpZztcbiAgICBjb25zdCB0ZXN0Q29ubiA9IFNvbmFtdS5kYkNvbmZpZy50ZXN0LmNvbm5lY3Rpb24gYXMgS25leC5QZ0Nvbm5lY3Rpb25Db25maWc7XG5cbiAgICAvLyAxLiDroZzsu6wgdGVzdCBEQiDsl7DqsrAg7KKF66OMIOuwjyDsnqzsg53shLFcbiAgICBjb25zdCB0ZXN0UGdFbnYgPSB7IFBHUEFTU1dPUkQ6IHRlc3RDb25uLnBhc3N3b3JkIHx8IFwiXCIgfTtcbiAgICBleGVjU3luYyhcbiAgICAgIGBwc3FsIC1oICR7dGVzdENvbm4uaG9zdH0gLXAgJHt0ZXN0Q29ubi5wb3J0ID8/IDU0MzJ9IC1VICR7dGVzdENvbm4udXNlcn0gLWQgcG9zdGdyZXMgLWMgXCJcbiAgICAgICAgU0VMRUNUIHBnX3Rlcm1pbmF0ZV9iYWNrZW5kKHBnX3N0YXRfYWN0aXZpdHkucGlkKVxuICAgICAgICBGUk9NIHBnX3N0YXRfYWN0aXZpdHlcbiAgICAgICAgV0hFUkUgZGF0bmFtZSA9ICcke3Rlc3RDb25uLmRhdGFiYXNlfSdcbiAgICAgICAgICBBTkQgcGlkIDw+IHBnX2JhY2tlbmRfcGlkKCk7XG4gICAgICBcImAsXG4gICAgICB7IHN0ZGlvOiBcImluaGVyaXRcIiwgZW52OiB7IC4uLnByb2Nlc3MuZW52LCAuLi50ZXN0UGdFbnYgfSBhcyBOb2RlSlMuUHJvY2Vzc0VudiB9LFxuICAgICk7XG5cbiAgICBleGVjU3luYyhcbiAgICAgIGBwc3FsIC1oICR7dGVzdENvbm4uaG9zdH0gLXAgJHt0ZXN0Q29ubi5wb3J0ID8/IDU0MzJ9IC1VICR7dGVzdENvbm4udXNlcn0gLWQgcG9zdGdyZXMgLWMgXCJEUk9QIERBVEFCQVNFIElGIEVYSVNUUyBcXFxcXCIke3Rlc3RDb25uLmRhdGFiYXNlfVxcXFxcIlwiYCxcbiAgICAgIHsgc3RkaW86IFwiaW5oZXJpdFwiLCBlbnY6IHsgLi4ucHJvY2Vzcy5lbnYsIC4uLnRlc3RQZ0VudiB9IGFzIE5vZGVKUy5Qcm9jZXNzRW52IH0sXG4gICAgKTtcblxuICAgIGV4ZWNTeW5jKFxuICAgICAgYHBzcWwgLWggJHt0ZXN0Q29ubi5ob3N0fSAtcCAke3Rlc3RDb25uLnBvcnQgPz8gNTQzMn0gLVUgJHt0ZXN0Q29ubi51c2VyfSAtZCBwb3N0Z3JlcyAtYyBcIkNSRUFURSBEQVRBQkFTRSBcXFxcXCIke3Rlc3RDb25uLmRhdGFiYXNlfVxcXFxcIlwiYCxcbiAgICAgIHsgc3RkaW86IFwiaW5oZXJpdFwiLCBlbnY6IHsgLi4ucHJvY2Vzcy5lbnYsIC4uLnRlc3RQZ0VudiB9IGFzIE5vZGVKUy5Qcm9jZXNzRW52IH0sXG4gICAgKTtcblxuICAgIC8vIDIuIOybkOqyqSBmaXh0dXJlIERCIOKGkiDroZzsu6wgdGVzdCBEQuuhnCDrs7XsgqwgKHBnX2R1bXAgfCBwZ19yZXN0b3JlKVxuICAgIGNvbnN0IGZpeHR1cmVQZ0VudiA9IHsgUEdQQVNTV09SRDogZml4dHVyZUNvbm4ucGFzc3dvcmQgfHwgXCJcIiB9O1xuICAgIGNvbnN0IGR1bXBDbWQgPSBgcGdfZHVtcCAtaCAke2ZpeHR1cmVDb25uLmhvc3R9IC1wICR7Zml4dHVyZUNvbm4ucG9ydCA/PyA1NDMyfSAtVSAke2ZpeHR1cmVDb25uLnVzZXJ9IC1kICR7Zml4dHVyZUNvbm4uZGF0YWJhc2V9IC1GY2A7XG4gICAgY29uc3QgcmVzdG9yZUNtZCA9IGBwZ19yZXN0b3JlIC1oICR7dGVzdENvbm4uaG9zdH0gLXAgJHt0ZXN0Q29ubi5wb3J0ID8/IDU0MzJ9IC1VICR7dGVzdENvbm4udXNlcn0gLWQgJHt0ZXN0Q29ubi5kYXRhYmFzZX0gLS1uby1vd25lciAtLW5vLWFjbGA7XG5cbiAgICBleGVjU3luYyhgJHtkdW1wQ21kfSB8IFBHUEFTU1dPUkQ9XCIke3Rlc3RDb25uLnBhc3N3b3JkIHx8IFwiXCJ9XCIgJHtyZXN0b3JlQ21kfWAsIHtcbiAgICAgIHN0ZGlvOiBcImluaGVyaXRcIixcbiAgICAgIGVudjogeyAuLi5wcm9jZXNzLmVudiwgLi4uZml4dHVyZVBnRW52IH0gYXMgTm9kZUpTLlByb2Nlc3NFbnYsXG4gICAgICBzaGVsbDogXCIvYmluL2Jhc2hcIixcbiAgICB9KTtcblxuICAgIC8vIDMuIOyLnO2AgOyKpCDrpqzshYsgKOuNsOydtO2EsCDrs7Xsgqwg7ZuEIOyLnO2AgOyKpOulvCBNQVgoaWQp66GcIOygleugrClcbiAgICBhd2FpdCB0aGlzLnJlc2V0U2VxdWVuY2VzKFNvbmFtdS5kYkNvbmZpZy50ZXN0KTtcbiAgfVxuXG4gIC8qKlxuICAgKiDrqqjrk6Ag7YWM7J2067iU7J2YIOyLnO2AgOyKpOulvCDtmITsnqwgTUFYKGlkKeuhnCDrpqzshYvtlanri4jri6QuXG4gICAqIGZpeHR1cmUgc3luYyDtm4Qg7Iuc7YCA7Iqk6rCAIOyLpOygnCDrjbDsnbTthLDsmYAg66ee7KeAIOyViuuKlCDrrLjsoJzrpbwg7ZW06rKw7ZWp64uI64ukLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyByZXNldFNlcXVlbmNlcyhkYkNvbmZpZzogU29uYW11REJDb25maWdbXCJ0ZXN0XCJdKSB7XG4gICAgY29uc3QgdGVzdERiID0gY3JlYXRlS25leEluc3RhbmNlKGRiQ29uZmlnKTtcbiAgICBjb25zdCBlbnRpdGllcyA9IEVudGl0eU1hbmFnZXIuZ2V0QWxsRW50aXRpZXMoKTtcblxuICAgIHRyeSB7XG4gICAgICBmb3IgKGNvbnN0IGVudGl0eSBvZiBlbnRpdGllcykge1xuICAgICAgICBjb25zdCB0YWJsZU5hbWUgPSBlbnRpdHkudGFibGUgfHwgZW50aXR5LmlkLnRvTG93ZXJDYXNlKCk7XG5cbiAgICAgICAgLy8gaWQg7ZWE65Oc7J2YIO2DgOyeheydhCDtmZXsnbjtlanri4jri6RcbiAgICAgICAgY29uc3QgaWRQcm9wID0gZW50aXR5LnByb3BzLmZpbmQoKHApID0+IHAubmFtZSA9PT0gXCJpZFwiKTtcbiAgICAgICAgY29uc3QgaWRUeXBlID0gaWRQcm9wPy50eXBlO1xuXG4gICAgICAgIC8vIGludGVnZXIvYmlnSW50ZWdlcuydtOqxsOuCmCwgc3RyaW5n7J207KeA66eMIGZpeHR1cmVTdHJhdGVneT1zZXF1ZW5jZeyduCDqsr3smrDsl5Drp4wg66as7IWL7ZWp64uI64ukXG4gICAgICAgIGNvbnN0IHVzZXNTZXF1ZW5jZSA9XG4gICAgICAgICAgaWRUeXBlID09PSBcImludGVnZXJcIiB8fFxuICAgICAgICAgIGlkVHlwZSA9PT0gXCJiaWdJbnRlZ2VyXCIgfHxcbiAgICAgICAgICBpZFByb3A/LmNvbmU/LmZpeHR1cmVTdHJhdGVneSA9PT0gXCJzZXF1ZW5jZVwiO1xuXG4gICAgICAgIGlmICghdXNlc1NlcXVlbmNlKSB7XG4gICAgICAgICAgIWlzVGVzdCgpICYmXG4gICAgICAgICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgICAgICAgYFNraXBwaW5nIHNlcXVlbmNlIHJlc2V0IGZvciAke3RhYmxlTmFtZX0gKGlkIHR5cGU6ICR7aWRUeXBlIHx8IFwidW5rbm93blwifSlgLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFBvc3RncmVTUUwg7Iuc7YCA7Iqk66W8IO2YhOyerCDthYzsnbTruJTsnZggTUFYKGlkKeuhnCDrpqzshYvtlanri4jri6QuXG4gICAgICAgIC8vIHN0cmluZyDtg4DsnoXsnZgg6rK97JqwIOyIq+yekCDsupDsiqTtjIXsnbQg7ZWE7JqU7ZWp64uI64ukLlxuICAgICAgICBjb25zdCBtYXhFeHByID0gaWRUeXBlID09PSBcInN0cmluZ1wiID8gXCJNQVgoaWQ6OmJpZ2ludClcIiA6IFwiTUFYKGlkKVwiO1xuICAgICAgICBhd2FpdCB0ZXN0RGIucmF3KGBcbiAgICAgICAgICBTRUxFQ1Qgc2V0dmFsKFxuICAgICAgICAgICAgcGdfZ2V0X3NlcmlhbF9zZXF1ZW5jZSgncHVibGljLiR7dGFibGVOYW1lfScsICdpZCcpLFxuICAgICAgICAgICAgQ09BTEVTQ0UoKFNFTEVDVCAke21heEV4cHJ9IEZST00gJHt0YWJsZU5hbWV9KSwgMSlcbiAgICAgICAgICApXG4gICAgICAgIGApO1xuICAgICAgfVxuICAgIH0gZmluYWxseSB7XG4gICAgICBhd2FpdCB0ZXN0RGIuZGVzdHJveSgpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgdmlzaXRlZFJlY29yZHMgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgYXN5bmMgaW1wb3J0Rml4dHVyZShlbnRpdHlJZDogc3RyaW5nLCBpZHM6IG51bWJlcltdKSB7XG4gICAgLy8g67Cp66y4IOq4sOuhnSDstIjquLDtmZQgKOyDiOuhnOyatCBpbXBvcnQg7J6R7JeFIOyLnOyekSlcbiAgICB0aGlzLnZpc2l0ZWRSZWNvcmRzLmNsZWFyKCk7XG5cbiAgICBjb25zdCBxdWVyaWVzID0gdW5pcXVlKFxuICAgICAgKFxuICAgICAgICBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgICAgICBpZHMubWFwKGFzeW5jIChpZCkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuZ2V0SW1wb3J0UXVlcmllcyhlbnRpdHlJZCwgXCJpZFwiLCBpZCk7XG4gICAgICAgICAgfSksXG4gICAgICAgIClcbiAgICAgICkuZmxhdCgpLFxuICAgICk7XG5cbiAgICBjb25zdCB3ZGIgPSBCYXNlTW9kZWwuZ2V0REIoXCJ3XCIpO1xuICAgIGZvciAoY29uc3QgcXVlcnkgb2YgcXVlcmllcykge1xuICAgICAgYXdhaXQgd2RiLnJhdyhxdWVyeSk7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgZ2V0SW1wb3J0UXVlcmllcyhlbnRpdHlJZDogc3RyaW5nLCBmaWVsZDogc3RyaW5nLCBpZDogbnVtYmVyKTogUHJvbWlzZTxzdHJpbmdbXT4ge1xuICAgIGNvbnN0IHJlY29yZEtleSA9IGAke2VudGl0eUlkfSMke2ZpZWxkfSMke2lkfWA7XG5cbiAgICAvLyDsiJztmZgg7LC47KGwIOuwqeyngDog7J2066+4IOuwqeusuO2VnCDroIjsvZTrk5zripQg7Iqk7YK1XG4gICAgaWYgKHRoaXMudmlzaXRlZFJlY29yZHMuaGFzKHJlY29yZEtleSkpIHtcbiAgICAgIHJldHVybiBbXTtcbiAgICB9XG4gICAgdGhpcy52aXNpdGVkUmVjb3Jkcy5hZGQocmVjb3JkS2V5KTtcblxuICAgIGNvbnN0IGVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0KGVudGl0eUlkKTtcbiAgICBjb25zdCB3ZGIgPSBCYXNlTW9kZWwuZ2V0REIoXCJ3XCIpO1xuXG4gICAgLy8g7Jes6riw7IScIOyLpERC7J2YIHJvdyDqsIDsoLjsmLRcbiAgICBjb25zdCBbcm93XSA9IGF3YWl0IHdkYihlbnRpdHkudGFibGUpLndoZXJlKGZpZWxkLCBpZCkubGltaXQoMSk7XG4gICAgaWYgKHJvdyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7ZW50aXR5SWR9IyR7aWR9IHJvd+ulvCDssL7snYQg7IiYIOyXhuyKteuLiOuLpC5gKTtcbiAgICB9XG5cbiAgICAvLyDtlL3siqTss5BEQiwg7IukREJcbiAgICBjb25zdCBmaXh0dXJlRGF0YWJhc2UgPSAoU29uYW11LmRiQ29uZmlnLmZpeHR1cmUuY29ubmVjdGlvbiBhcyBLbmV4LkNvbm5lY3Rpb25Db25maWcpLmRhdGFiYXNlO1xuICAgIGNvbnN0IHJlYWxEYXRhYmFzZSA9IChTb25hbXUuZGJDb25maWcucHJvZHVjdGlvbi5jb25uZWN0aW9uIGFzIEtuZXguQ29ubmVjdGlvbkNvbmZpZykuZGF0YWJhc2U7XG5cbiAgICBjb25zdCBzZWxmUXVlcnkgPSBgSU5TRVJUIElHTk9SRSBJTlRPIFxcYCR7Zml4dHVyZURhdGFiYXNlfVxcYC5cXGAke2VudGl0eS50YWJsZX1cXGAgKFNFTEVDVCAqIEZST00gXFxgJHtyZWFsRGF0YWJhc2V9XFxgLlxcYCR7ZW50aXR5LnRhYmxlfVxcYCBXSEVSRSBcXGBpZFxcYCA9ICR7aWR9KWA7XG5cbiAgICBjb25zdCBhcmdzID0gT2JqZWN0LmVudHJpZXMoZW50aXR5LnJlbGF0aW9ucylcbiAgICAgIC5maWx0ZXIoXG4gICAgICAgIChbLCByZWxhdGlvbl0pID0+XG4gICAgICAgICAgaXNCZWxvbmdzVG9PbmVSZWxhdGlvblByb3AocmVsYXRpb24pIHx8XG4gICAgICAgICAgKGlzT25lVG9PbmVSZWxhdGlvblByb3AocmVsYXRpb24pICYmIHJlbGF0aW9uLmN1c3RvbUpvaW5DbGF1c2UgPT09IHVuZGVmaW5lZCksXG4gICAgICApXG4gICAgICAubWFwKChbLCByZWxhdGlvbl0pID0+IHtcbiAgICAgICAgLypcbiAgICAgICAgQmVsb25nc1RvT25l7J24IOqyveyasFxuICAgICAgICAgIENhdGVnb3J5IC8gJ2lkJyAvIHJvd1tjYXRlZ29yeV9pZF0g7Zi47LacXG4gICAgICAgIE9uZVRvT25l7JeQIGpvaW5Db2x1bW4gPT09IHRydWUg7J24IOqyveyasFxuICAgICAgICAgIFByb2ZpbGUgLyAnaWQnIC8gcm93W3Byb2ZpbGVfaWRdIO2YuOy2nFxuICAgICAgICBPbmVUb09uZeyXkCBqb2luQ29sdW1uID09PSBmYWxzZSDsnbgg6rK97JqwXG4gICAgICAgICAgUHJvZmlsZSAvICdwcm9maWxlX2lkJyAvIHJvd1snaWQnXSDtmLjstpxcbiAgICAgICAgKi9cbiAgICAgICAgbGV0IGZpZWxkOiBzdHJpbmc7XG4gICAgICAgIGxldCBpZDogbnVtYmVyO1xuICAgICAgICBpZiAoaXNPbmVUb09uZVJlbGF0aW9uUHJvcChyZWxhdGlvbikgJiYgIXJlbGF0aW9uLmhhc0pvaW5Db2x1bW4pIHtcbiAgICAgICAgICBjb25zdCByZWxhdGVkRW50aXR5ID0gRW50aXR5TWFuYWdlci5nZXQocmVsYXRpb24ud2l0aCk7XG4gICAgICAgICAgY29uc3QgcmVsYXRlZElkQ29sdW1uTmFtZSA9IHJlbGF0ZWRFbnRpdHkucHJvcHMuZmluZChcbiAgICAgICAgICAgIChwKSA9PiBpc1JlbGF0aW9uUHJvcChwKSAmJiBwLndpdGggPT09IGVudGl0eS5pZCxcbiAgICAgICAgICApPy5uYW1lO1xuICAgICAgICAgIGlmICghcmVsYXRlZElkQ29sdW1uTmFtZSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke3JlbGF0ZWRFbnRpdHkuaWR97J2YICR7ZW50aXR5LmlkfSDqtIDqs4Qg7ZSE66Gt7J2EIOywvuydhCDsiJgg7JeG7Iq164uI64ukLmApO1xuICAgICAgICAgIH1cbiAgICAgICAgICBmaWVsZCA9IGAke3JlbGF0ZWRJZENvbHVtbk5hbWV9X2lkYDtcbiAgICAgICAgICBpZCA9IHJvdy5pZDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBmaWVsZCA9IFwiaWRcIjtcbiAgICAgICAgICBpZCA9IHJvd1tgJHtyZWxhdGlvbi5uYW1lfV9pZGBdO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgZW50aXR5SWQ6IHJlbGF0aW9uLndpdGgsXG4gICAgICAgICAgZmllbGQsXG4gICAgICAgICAgaWQsXG4gICAgICAgIH07XG4gICAgICB9KVxuICAgICAgLmZpbHRlcigoYXJnKSA9PiBhcmcuaWQgIT09IG51bGwpO1xuXG4gICAgY29uc3QgcmVsUXVlcmllcyA9IGF3YWl0IFByb21pc2UuYWxsKFxuICAgICAgYXJncy5tYXAoYXN5bmMgKGFyZ3MpID0+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0SW1wb3J0UXVlcmllcyhhcmdzLmVudGl0eUlkLCBhcmdzLmZpZWxkLCBhcmdzLmlkKTtcbiAgICAgIH0pLFxuICAgICk7XG5cbiAgICByZXR1cm4gWy4uLnVuaXF1ZShyZWxRdWVyaWVzLnRvUmV2ZXJzZWQoKS5mbGF0KCkpLCBzZWxmUXVlcnldO1xuICB9XG5cbiAgYXN5bmMgZGVzdHJveSgpIHtcbiAgICBpZiAodGhpcy5fdGRiKSB7XG4gICAgICBhd2FpdCB0aGlzLl90ZGIuZGVzdHJveSgpO1xuICAgICAgdGhpcy5fdGRiID0gbnVsbDtcbiAgICB9XG4gICAgaWYgKHRoaXMuX2ZkYikge1xuICAgICAgYXdhaXQgdGhpcy5fZmRiLmRlc3Ryb3koKTtcbiAgICAgIHRoaXMuX2ZkYiA9IG51bGw7XG4gICAgfVxuICAgIGF3YWl0IEJhc2VNb2RlbC5kZXN0cm95KCk7XG4gIH1cblxuICBhc3luYyBnZXRGaXh0dXJlcyhcbiAgICBzb3VyY2VEQk5hbWU6IGtleW9mIFNvbmFtdURCQ29uZmlnLFxuICAgIHRhcmdldERCTmFtZToga2V5b2YgU29uYW11REJDb25maWcsXG4gICAgc2VhcmNoT3B0aW9uczogRml4dHVyZVNlYXJjaE9wdGlvbnMsXG4gICAgZHVwbGljYXRlQ2hlY2s/OiBEdXBsaWNhdGVDaGVja09wdGlvbnMsXG4gICkge1xuICAgIGNvbnN0IHNvdXJjZURCID0gY3JlYXRlS25leEluc3RhbmNlKFNvbmFtdS5kYkNvbmZpZ1tzb3VyY2VEQk5hbWVdKTtcbiAgICBjb25zdCB0YXJnZXREQiA9IGNyZWF0ZUtuZXhJbnN0YW5jZShTb25hbXUuZGJDb25maWdbdGFyZ2V0REJOYW1lXSk7XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgeyBlbnRpdHlJZCwgZmllbGQsIHZhbHVlLCBzZWFyY2hUeXBlIH0gPSBzZWFyY2hPcHRpb25zO1xuXG4gICAgICBjb25zdCBlbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChlbnRpdHlJZCk7XG4gICAgICBjb25zdCBjb2x1bW4gPVxuICAgICAgICBlbnRpdHkucHJvcHMuZmluZCgocHJvcCkgPT4gcHJvcC5uYW1lID09PSBmaWVsZCk/LnR5cGUgPT09IFwicmVsYXRpb25cIlxuICAgICAgICAgID8gYCR7ZmllbGR9X2lkYFxuICAgICAgICAgIDogZmllbGQ7XG5cbiAgICAgIGxldCBxdWVyeSA9IHNvdXJjZURCKGVudGl0eS50YWJsZSk7XG4gICAgICBpZiAoc2VhcmNoVHlwZSA9PT0gXCJlcXVhbHNcIikge1xuICAgICAgICBxdWVyeSA9IHF1ZXJ5LndoZXJlKGNvbHVtbiwgdmFsdWUpO1xuICAgICAgfSBlbHNlIGlmIChzZWFyY2hUeXBlID09PSBcImxpa2VcIikge1xuICAgICAgICBxdWVyeSA9IHF1ZXJ5LndoZXJlKGNvbHVtbiwgXCJsaWtlXCIsIGAlJHt2YWx1ZX0lYCk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHJvd3MgPSBhd2FpdCBxdWVyeTtcbiAgICAgIGlmIChyb3dzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJObyByZWNvcmRzIGZvdW5kXCIpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBmaXh0dXJlczogRml4dHVyZVJlY29yZFtdID0gW107XG4gICAgICBmb3IgKGNvbnN0IHJvdyBvZiByb3dzKSB7XG4gICAgICAgIGNvbnN0IGluaXRpYWxSZWNvcmRzTGVuZ3RoID0gZml4dHVyZXMubGVuZ3RoO1xuICAgICAgICBjb25zdCBuZXdSZWNvcmRzID0gYXdhaXQgdGhpcy5jcmVhdGVGaXh0dXJlUmVjb3JkKGVudGl0eSwgcm93LCB7XG4gICAgICAgICAgX2RiOiBzb3VyY2VEQixcbiAgICAgICAgfSk7XG4gICAgICAgIGZpeHR1cmVzLnB1c2goLi4ubmV3UmVjb3Jkcyk7XG4gICAgICAgIGNvbnN0IGN1cnJlbnRGaXh0dXJlUmVjb3JkID0gZml4dHVyZXMuZmluZCgocikgPT4gci5maXh0dXJlSWQgPT09IGAke2VudGl0eUlkfSMke3Jvdy5pZH1gKTtcblxuICAgICAgICBpZiAoY3VycmVudEZpeHR1cmVSZWNvcmQpIHtcbiAgICAgICAgICAvLyDtmITsnqwgZml4dHVyZeuhnOu2gO2EsCDsg53shLHrkJwgZmV0Y2hlZFJlY29yZHMg7ISk7KCVXG4gICAgICAgICAgY3VycmVudEZpeHR1cmVSZWNvcmQuZmV0Y2hlZFJlY29yZHMgPSBmaXh0dXJlc1xuICAgICAgICAgICAgLmZpbHRlcigocikgPT4gci5maXh0dXJlSWQgIT09IGN1cnJlbnRGaXh0dXJlUmVjb3JkLmZpeHR1cmVJZClcbiAgICAgICAgICAgIC5zbGljZShpbml0aWFsUmVjb3Jkc0xlbmd0aClcbiAgICAgICAgICAgIC5tYXAoKHIpID0+IHIuZml4dHVyZUlkKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBmb3IgKGNvbnN0IGZpeHR1cmUgb2YgZml4dHVyZXMpIHtcbiAgICAgICAgY29uc3QgZW50aXR5ID0gRW50aXR5TWFuYWdlci5nZXQoZml4dHVyZS5lbnRpdHlJZCk7XG5cbiAgICAgICAgLy8g7IKs7Jqp7J6QIOyngOyglSDsu6zrn7wg6riw7KSAIOykkeuztSDtmZXsnbgg4oaSIHRhcmdldFxuICAgICAgICBjb25zdCBjdXN0b21Db2x1bW5zID0gZHVwbGljYXRlQ2hlY2s/LmNvbHVtbnM/LltmaXh0dXJlLmVudGl0eUlkXTtcbiAgICAgICAgaWYgKGN1c3RvbUNvbHVtbnMgJiYgY3VzdG9tQ29sdW1ucy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgY29uc3QgY3VzdG9tRHVwbGljYXRlUm93ID0gYXdhaXQgdGhpcy5jaGVja0R1cGxpY2F0ZUJ5Q29sdW1ucyhcbiAgICAgICAgICAgIHRhcmdldERCLFxuICAgICAgICAgICAgZW50aXR5LFxuICAgICAgICAgICAgZml4dHVyZSxcbiAgICAgICAgICAgIGN1c3RvbUNvbHVtbnMsXG4gICAgICAgICAgKTtcbiAgICAgICAgICBpZiAoY3VzdG9tRHVwbGljYXRlUm93KSB7XG4gICAgICAgICAgICBjb25zdCBbcmVjb3JkXSA9IGF3YWl0IHRoaXMuY3JlYXRlRml4dHVyZVJlY29yZChlbnRpdHksIGN1c3RvbUR1cGxpY2F0ZVJvdywge1xuICAgICAgICAgICAgICBzaW5nbGVSZWNvcmQ6IHRydWUsXG4gICAgICAgICAgICAgIF9kYjogdGFyZ2V0REIsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGZpeHR1cmUudGFyZ2V0ID0gcmVjb3JkO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFVuaXF1ZSBpbmRleCDquLDspIAg7KSR67O1IO2ZleyduCDihpIgZml4dHVyZS51bmlxdWVcbiAgICAgICAgY29uc3QgdW5pcXVlUm93ID0gYXdhaXQgdGhpcy5jaGVja1VuaXF1ZVZpb2xhdGlvbih0YXJnZXREQiwgZW50aXR5LCBmaXh0dXJlKTtcbiAgICAgICAgaWYgKHVuaXF1ZVJvdykge1xuICAgICAgICAgIGNvbnN0IFtyZWNvcmRdID0gYXdhaXQgdGhpcy5jcmVhdGVGaXh0dXJlUmVjb3JkKGVudGl0eSwgdW5pcXVlUm93LCB7XG4gICAgICAgICAgICBzaW5nbGVSZWNvcmQ6IHRydWUsXG4gICAgICAgICAgICBfZGI6IHRhcmdldERCLFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIGZpeHR1cmUudW5pcXVlID0gcmVjb3JkO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB1bmlxdWUoZml4dHVyZXMsIChmKSA9PiBmLmZpeHR1cmVJZCk7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIGF3YWl0IFByb21pc2UuYWxsU2V0dGxlZChbdGFyZ2V0REIuZGVzdHJveSgpLCBzb3VyY2VEQi5kZXN0cm95KCldKTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBjcmVhdGVGaXh0dXJlUmVjb3JkKFxuICAgIGVudGl0eTogRW50aXR5LFxuICAgIHJvdzoge1xuICAgICAgaWQ6IG51bWJlciB8IHN0cmluZztcbiAgICAgIFtrZXk6IHN0cmluZ106IHN0cmluZyB8IG51bWJlciB8IGJvb2xlYW4gfCBudWxsO1xuICAgIH0sXG4gICAgb3B0aW9ucz86IHtcbiAgICAgIHNpbmdsZVJlY29yZD86IGJvb2xlYW47XG4gICAgICBfZGI/OiBLbmV4O1xuICAgIH0sXG4gICk6IFByb21pc2U8Rml4dHVyZVJlY29yZFtdPiB7XG4gICAgY29uc3QgcmVjb3JkczogRml4dHVyZVJlY29yZFtdID0gW107XG4gICAgY29uc3QgdmlzaXRlZEVudGl0aWVzID0gbmV3IFNldDxzdHJpbmc+KCk7XG5cbiAgICBjb25zdCBjcmVhdGUgPSBhc3luYyAoXG4gICAgICBlbnRpdHk6IEVudGl0eSxcbiAgICAgIHJvdzoge1xuICAgICAgICBpZDogbnVtYmVyIHwgc3RyaW5nO1xuICAgICAgICBba2V5OiBzdHJpbmddOiBzdHJpbmcgfCBudW1iZXIgfCBib29sZWFuIHwgbnVsbDtcbiAgICAgIH0sXG4gICAgKSA9PiB7XG4gICAgICBjb25zdCBmaXh0dXJlSWQgPSBgJHtlbnRpdHkuaWR9IyR7cm93LmlkfWA7XG4gICAgICBpZiAodmlzaXRlZEVudGl0aWVzLmhhcyhmaXh0dXJlSWQpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHZpc2l0ZWRFbnRpdGllcy5hZGQoZml4dHVyZUlkKTtcblxuICAgICAgY29uc3QgcmVjb3JkOiBGaXh0dXJlUmVjb3JkID0ge1xuICAgICAgICBmaXh0dXJlSWQsXG4gICAgICAgIGVudGl0eUlkOiBlbnRpdHkuaWQsXG4gICAgICAgIGlkOiByb3cuaWQsXG4gICAgICAgIGNvbHVtbnM6IHt9LFxuICAgICAgICBmZXRjaGVkUmVjb3JkczogW10sXG4gICAgICAgIGJlbG9uZ3NSZWNvcmRzOiBbXSxcbiAgICAgIH07XG5cbiAgICAgIGZvciAoY29uc3QgcHJvcCBvZiBlbnRpdHkucHJvcHMpIHtcbiAgICAgICAgaWYgKGlzVmlydHVhbFByb3AocHJvcCkpIHtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJlY29yZC5jb2x1bW5zW3Byb3AubmFtZV0gPSB7XG4gICAgICAgICAgcHJvcDogcHJvcCxcbiAgICAgICAgICB2YWx1ZTogcm93W3Byb3AubmFtZV0sXG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3QgZGIgPSBvcHRpb25zPy5fZGIgPz8gQmFzZU1vZGVsLmdldERCKFwid1wiKTtcbiAgICAgICAgaWYgKGlzTWFueVRvTWFueVJlbGF0aW9uUHJvcChwcm9wKSkge1xuICAgICAgICAgIGNvbnN0IHJlbGF0ZWRFbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChwcm9wLndpdGgpO1xuICAgICAgICAgIGNvbnN0IHRocm91Z2hUYWJsZSA9IHByb3Auam9pblRhYmxlO1xuICAgICAgICAgIGNvbnN0IGZyb21Db2x1bW4gPSBgJHtpbmZsZWN0aW9uLnNpbmd1bGFyaXplKGVudGl0eS50YWJsZSl9X2lkYDtcbiAgICAgICAgICBjb25zdCB0b0NvbHVtbiA9IGAke2luZmxlY3Rpb24uc2luZ3VsYXJpemUocmVsYXRlZEVudGl0eS50YWJsZSl9X2lkYDtcblxuICAgICAgICAgIGNvbnN0IHJlbGF0ZWRJZHMgPSBhd2FpdCBkYih0aHJvdWdoVGFibGUpLndoZXJlKGZyb21Db2x1bW4sIHJvdy5pZCkucGx1Y2sodG9Db2x1bW4pO1xuICAgICAgICAgIHJlY29yZC5jb2x1bW5zW3Byb3AubmFtZV0udmFsdWUgPSByZWxhdGVkSWRzO1xuICAgICAgICB9IGVsc2UgaWYgKGlzSGFzTWFueVJlbGF0aW9uUHJvcChwcm9wKSkge1xuICAgICAgICAgIGNvbnN0IHJlbGF0ZWRFbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChwcm9wLndpdGgpO1xuICAgICAgICAgIGNvbnN0IHJlbGF0ZWRJZHMgPSBhd2FpdCBkYihyZWxhdGVkRW50aXR5LnRhYmxlKVxuICAgICAgICAgICAgLndoZXJlKHByb3Auam9pbkNvbHVtbiwgcm93LmlkKVxuICAgICAgICAgICAgLnBsdWNrKFwiaWRcIik7XG4gICAgICAgICAgcmVjb3JkLmNvbHVtbnNbcHJvcC5uYW1lXS52YWx1ZSA9IHJlbGF0ZWRJZHM7XG4gICAgICAgIH0gZWxzZSBpZiAoaXNPbmVUb09uZVJlbGF0aW9uUHJvcChwcm9wKSAmJiAhcHJvcC5oYXNKb2luQ29sdW1uKSB7XG4gICAgICAgICAgLy8g7Jet67Cp7ZalIE9uZVRvT25lOiBGS+ulvCDqsIDsp4Qg6rSA66CoIOyXlO2LsO2LsOulvCDssL7sirXri4jri6RcbiAgICAgICAgICAvLyDsmIjsi5w6IFVzZXIgT25lVG9PbmUgRW1wbG95ZWUgKEVtcGxveWVl6rCAIHVzZXJfaWQgRkvrpbwg6rCA7KeQKVxuICAgICAgICAgIGNvbnN0IHJlbGF0ZWRFbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChwcm9wLndpdGgpO1xuICAgICAgICAgIGNvbnN0IHJlbGF0ZWRQcm9wID0gcmVsYXRlZEVudGl0eS5wcm9wcy5maW5kKFxuICAgICAgICAgICAgKHApID0+IGlzUmVsYXRpb25Qcm9wKHApICYmIHAud2l0aCA9PT0gZW50aXR5LmlkLFxuICAgICAgICAgICk7XG4gICAgICAgICAgaWYgKHJlbGF0ZWRQcm9wICYmIGlzUmVsYXRpb25Qcm9wKHJlbGF0ZWRQcm9wKSkge1xuICAgICAgICAgICAgLy8g6rSA66CoIOyXlO2LsO2LsOyXkOyEnCBGSyDsu6zrn7zsnLzroZwg7L+866as7ZWp64uI64ukIChpZOqwgCDslYTri5gpXG4gICAgICAgICAgICBjb25zdCBma0NvbHVtbiA9IGAke3JlbGF0ZWRQcm9wLm5hbWV9X2lkYDtcbiAgICAgICAgICAgIGNvbnN0IHJlbGF0ZWRSb3cgPSBhd2FpdCBkYihyZWxhdGVkRW50aXR5LnRhYmxlKS53aGVyZShma0NvbHVtbiwgcm93LmlkKS5maXJzdCgpO1xuICAgICAgICAgICAgcmVjb3JkLmNvbHVtbnNbcHJvcC5uYW1lXS52YWx1ZSA9IHJlbGF0ZWRSb3c/LmlkO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmIChpc1JlbGF0aW9uUHJvcChwcm9wKSkge1xuICAgICAgICAgIGNvbnN0IHJlbGF0ZWRJZCA9IHJvd1tgJHtwcm9wLm5hbWV9X2lkYF07XG4gICAgICAgICAgcmVjb3JkLmNvbHVtbnNbcHJvcC5uYW1lXS52YWx1ZSA9IHJlbGF0ZWRJZDtcbiAgICAgICAgICBpZiAocmVsYXRlZElkKSB7XG4gICAgICAgICAgICByZWNvcmQuYmVsb25nc1JlY29yZHMucHVzaChgJHtwcm9wLndpdGh9IyR7cmVsYXRlZElkfWApO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoIW9wdGlvbnM/LnNpbmdsZVJlY29yZCAmJiByZWxhdGVkSWQpIHtcbiAgICAgICAgICAgIGNvbnN0IHJlbGF0ZWRFbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChwcm9wLndpdGgpO1xuICAgICAgICAgICAgY29uc3QgcmVsYXRlZFJvdyA9IGF3YWl0IGRiKHJlbGF0ZWRFbnRpdHkudGFibGUpLndoZXJlKFwiaWRcIiwgcmVsYXRlZElkKS5maXJzdCgpO1xuICAgICAgICAgICAgaWYgKHJlbGF0ZWRSb3cpIHtcbiAgICAgICAgICAgICAgYXdhaXQgY3JlYXRlKHJlbGF0ZWRFbnRpdHksIHJlbGF0ZWRSb3cpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZWNvcmRzLnB1c2gocmVjb3JkKTtcbiAgICB9O1xuXG4gICAgYXdhaXQgY3JlYXRlKGVudGl0eSwgcm93KTtcblxuICAgIHJldHVybiByZWNvcmRzO1xuICB9XG5cbiAgLyoqXG4gICAqIDEuIFJlbGF0aW9uR3JhcGjroZwgZml4dHVyZSDri6jsnIQg7IK97J6FIOyInOyEnCDqs4TsgrAgKHNlbGYtcmVmZXJlbmNlIO2PrO2VqClcbiAgICogMi4g7YWM7J2067iU67OEIOugiOuyqOuzhOuhnCBVcHNlcnRCdWlsZGVy7JeQIOuTseuhnSDrsI8gdXBzZXJ0IOyLpO2WiVxuICAgKiAzLiDsiJzshJwg6riw67CYIHV1aWTihpJpZCDrp6TtlZEgKFVwc2VydEJ1aWxkZXLqsIAgdXVpZOulvCBEQuyXkCDsoIDsnqXtlZjsp4Ag7JWK7Jy866+A66GcKVxuICAgKlxuICAgKiBVcHNlcnRCdWlsZGVy64qUIHNlbGYtcmVmZXJlbmNl6rCAIOyeiOycvOuptCBidWlsZEluc2VydExldmVscygp66GcIOyerOygleugrO2VmOyXrFxuICAgKiDrk7HroZ0g7Iic7ISc7JmAIOuwmO2ZmCDsiJzshJzqsIAg64us65287KeIIOyImCDsnojsirXri4jri6QuIOydtOulvCDrsKnsp4DtlZjquLAg7JyE7ZW0XG4gICAqIEZpeHR1cmVNYW5hZ2Vy6rCAIOugiOuyqOuzhOuhnCDrgpjriKDshJwg7LKY66as7ZWY7JesIOqwgSB1cHNlcnQg7Zi47Lac7JeQ7ISc64qUXG4gICAqIHNlbGYtcmVmZXJlbmNl6rCAIOyXhuuPhOuhnSDtlanri4jri6QuXG4gICAqL1xuICBhc3luYyBpbnNlcnRGaXh0dXJlcyhcbiAgICBkYk5hbWU6IGtleW9mIFNvbmFtdURCQ29uZmlnLFxuICAgIF9maXh0dXJlczogRml4dHVyZVJlY29yZFtdLFxuICApOiBQcm9taXNlPEZpeHR1cmVJbXBvcnRSZXN1bHRbXT4ge1xuICAgIGNvbnN0IGZpeHR1cmVzID0gdW5pcXVlKF9maXh0dXJlcywgKGYpID0+IGYuZml4dHVyZUlkKTtcblxuICAgIC8vIOy0iOq4sO2ZlFxuICAgIHRoaXMuYnVpbGRlciA9IG5ldyBVcHNlcnRCdWlsZGVyKCk7XG4gICAgdGhpcy5maXh0dXJlUmVmTWFwID0gbmV3IE1hcCgpO1xuICAgIHRoaXMuc2tpcHBlZEZpeHR1cmVzID0gbmV3IE1hcCgpO1xuXG4gICAgLy8g67OR66CsIO2FjOyKpO2KuCDrqqjrk5zsl5DshJzripQgd29ya2Vy67OEIERC7JeQIOyggOyepVxuICAgIGNvbnN0IGRiQ29uZmlnID1cbiAgICAgIHByb2Nlc3MuZW52LlNPTkFNVV9XT1JLRVJfREIgPT09IFwidHJ1ZVwiICYmIHByb2Nlc3MuZW52LlZJVEVTVF9QT09MX0lEXG4gICAgICAgID8gKCgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHdvcmtlcklkID0gcGFyc2VJbnQocHJvY2Vzcy5lbnYuVklURVNUX1BPT0xfSUQgPz8gXCIxXCIsIDEwKTtcbiAgICAgICAgICAgIGNvbnN0IGJhc2VDb25maWcgPSBTb25hbXUuZGJDb25maWdbZGJOYW1lXTtcbiAgICAgICAgICAgIGNvbnN0IGNvbm5lY3Rpb24gPSBiYXNlQ29uZmlnLmNvbm5lY3Rpb24gYXMgeyBkYXRhYmFzZTogc3RyaW5nIH07XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAuLi5iYXNlQ29uZmlnLFxuICAgICAgICAgICAgICBjb25uZWN0aW9uOiB7IC4uLmNvbm5lY3Rpb24sIGRhdGFiYXNlOiBgJHtjb25uZWN0aW9uLmRhdGFiYXNlfV8ke3dvcmtlcklkfWAgfSxcbiAgICAgICAgICAgICAgcG9vbDogeyBtaW46IDEsIG1heDogMSB9LFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9KSgpXG4gICAgICAgIDogU29uYW11LmRiQ29uZmlnW2RiTmFtZV07XG4gICAgY29uc3QgZGIgPSBjcmVhdGVLbmV4SW5zdGFuY2UoZGJDb25maWcpO1xuICAgIGNvbnN0IHJlc3VsdHM6IEZpeHR1cmVJbXBvcnRSZXN1bHRbXSA9IFtdO1xuXG4gICAgdHJ5IHtcbiAgICAgIC8vIDEuIFJlbGF0aW9uR3JhcGjroZwgZml4dHVyZSDri6jsnIQg7IK97J6FIOyInOyEnCDqs4TsgrBcbiAgICAgIHRoaXMucmVsYXRpb25HcmFwaC5idWlsZEdyYXBoKGZpeHR1cmVzKTtcbiAgICAgIGNvbnN0IGluc2VydGlvbk9yZGVyID0gdGhpcy5yZWxhdGlvbkdyYXBoLmdldEluc2VydGlvbk9yZGVyKCk7XG5cbiAgICAgIC8vIDIuIOyKpO2Cte2VoCBmaXh0dXJlIOuovOyggCDsspjrpqwgKG92ZXJyaWRlIOyytO2BrClcbiAgICAgIGZvciAoY29uc3QgZml4dHVyZUlkIG9mIGluc2VydGlvbk9yZGVyKSB7XG4gICAgICAgIGNvbnN0IGZpeHR1cmUgPSBmaXh0dXJlcy5maW5kKChmKSA9PiBmLmZpeHR1cmVJZCA9PT0gZml4dHVyZUlkKTtcbiAgICAgICAgaWYgKCFmaXh0dXJlKSBjb250aW51ZTtcblxuICAgICAgICBjb25zdCBoYXNUYXJnZXQgPSAhIWZpeHR1cmUudGFyZ2V0O1xuICAgICAgICBjb25zdCBoYXNVbmlxdWUgPSAhIWZpeHR1cmUudW5pcXVlO1xuICAgICAgICBjb25zdCBoYXNEdXBsaWNhdGUgPSBoYXNUYXJnZXQgfHwgaGFzVW5pcXVlO1xuXG4gICAgICAgIC8vIOykkeuzteydtCDsnojqs6Agb3ZlcnJpZGU9ZmFsc2Xsnbgg6rK97JqwOiDsiqTtgrVcbiAgICAgICAgaWYgKGhhc0R1cGxpY2F0ZSAmJiAhZml4dHVyZS5vdmVycmlkZSkge1xuICAgICAgICAgIC8vIOq4sOyhtCDroIjsvZTrk5wgSUQg7KCA7J6lICh1bmlxdWUg7Jqw7ISgLCDsl4bsnLzrqbQgdGFyZ2V0KVxuICAgICAgICAgIGNvbnN0IGV4aXN0aW5nSWQgPSBmaXh0dXJlLnVuaXF1ZT8uaWQgPz8gZml4dHVyZS50YXJnZXQ/LmlkO1xuICAgICAgICAgIGFzc2VydChleGlzdGluZ0lkKTtcbiAgICAgICAgICB0aGlzLnNraXBwZWRGaXh0dXJlcy5zZXQoZml4dHVyZUlkLCB7XG4gICAgICAgICAgICBlbnRpdHlJZDogZml4dHVyZS5lbnRpdHlJZCxcbiAgICAgICAgICAgIGV4aXN0aW5nSWQsXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICAhaXNUZXN0KCkgJiZcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICAgICAgICBjaGFsay55ZWxsb3coXG4gICAgICAgICAgICAgICAgYFNraXBwZWQgJHtmaXh0dXJlLmVudGl0eUlkfSMke2ZpeHR1cmUuaWR9IChleGlzdGluZzogIyR7ZXhpc3RpbmdJZH0sIG92ZXJyaWRlOiBmYWxzZSlgLFxuICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyAzLiDthYzsnbTruJTrs4QgZml4dHVyZSDqt7jro7ntmZQgKGluc2VydGlvbk9yZGVyIOyInOyEnCDquLDrsJgpXG4gICAgICBjb25zdCBmaXh0dXJlc0J5VGFibGUgPSBuZXcgTWFwPHN0cmluZywgRml4dHVyZVJlY29yZFtdPigpO1xuICAgICAgY29uc3QgdGFibGVPcmRlcjogc3RyaW5nW10gPSBbXTtcblxuICAgICAgZm9yIChjb25zdCBmaXh0dXJlSWQgb2YgaW5zZXJ0aW9uT3JkZXIpIHtcbiAgICAgICAgLy8g7Iqk7YK165CcIGZpeHR1cmUg7KCc7Jm4XG4gICAgICAgIGlmICh0aGlzLnNraXBwZWRGaXh0dXJlcy5oYXMoZml4dHVyZUlkKSkgY29udGludWU7XG5cbiAgICAgICAgY29uc3QgZml4dHVyZSA9IGZpeHR1cmVzLmZpbmQoKGYpID0+IGYuZml4dHVyZUlkID09PSBmaXh0dXJlSWQpO1xuICAgICAgICBpZiAoIWZpeHR1cmUpIGNvbnRpbnVlO1xuXG4gICAgICAgIGNvbnN0IGVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0KGZpeHR1cmUuZW50aXR5SWQpO1xuICAgICAgICBjb25zdCB0YWJsZU5hbWUgPSBlbnRpdHkudGFibGU7XG5cbiAgICAgICAgaWYgKCFmaXh0dXJlc0J5VGFibGUuaGFzKHRhYmxlTmFtZSkpIHtcbiAgICAgICAgICBmaXh0dXJlc0J5VGFibGUuc2V0KHRhYmxlTmFtZSwgW10pO1xuICAgICAgICAgIHRhYmxlT3JkZXIucHVzaCh0YWJsZU5hbWUpO1xuICAgICAgICB9XG4gICAgICAgIGZpeHR1cmVzQnlUYWJsZS5nZXQodGFibGVOYW1lKT8ucHVzaChmaXh0dXJlKTtcbiAgICAgIH1cblxuICAgICAgYXdhaXQgZGIudHJhbnNhY3Rpb24oYXN5bmMgKHRyeCkgPT4ge1xuICAgICAgICBjb25zdCBpbnNlcnRlZElkc0J5VGFibGUgPSBuZXcgTWFwPHN0cmluZywgTWFwPHN0cmluZywgbnVtYmVyIHwgc3RyaW5nPj4oKTtcblxuICAgICAgICAvLyA0LiDthYzsnbTruJTrs4Qg66CI67Ko67OEIOyymOumrFxuICAgICAgICBmb3IgKGNvbnN0IHRhYmxlTmFtZSBvZiB0YWJsZU9yZGVyKSB7XG4gICAgICAgICAgY29uc3QgdGFibGVGaXh0dXJlcyA9IGZpeHR1cmVzQnlUYWJsZS5nZXQodGFibGVOYW1lKSA/PyBbXTtcbiAgICAgICAgICBjb25zdCBsZXZlbHMgPSB0aGlzLmdyb3VwRml4dHVyZXNCeUxldmVsKHRhYmxlRml4dHVyZXMpO1xuXG4gICAgICAgICAgZm9yIChjb25zdCBsZXZlbEZpeHR1cmVzIG9mIGxldmVscykge1xuICAgICAgICAgICAgLy8g7ZW064u5IOugiOuyqOydmCBmaXh0dXJl65OkIHJlZ2lzdGVyXG4gICAgICAgICAgICBmb3IgKGNvbnN0IGZpeHR1cmUgb2YgbGV2ZWxGaXh0dXJlcykge1xuICAgICAgICAgICAgICB0aGlzLnJlZ2lzdGVyRml4dHVyZShmaXh0dXJlLCBpbnNlcnRlZElkc0J5VGFibGUpO1xuICAgICAgICAgICAgICAhaXNUZXN0KCkgJiZcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgICAgICAgICAgIGNoYWxrLmJsdWUoXG4gICAgICAgICAgICAgICAgICAgIGBSZWdpc3RlcmVkICR7Zml4dHVyZS5lbnRpdHlJZH0jJHtmaXh0dXJlLmlkfSR7Zml4dHVyZS5vdmVycmlkZSA/IGAgKG92ZXJyaWRlKWAgOiBcIlwifWAsXG4gICAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIHVwc2VydCDsi6Ttlokg7KCEIHV1aWQg66qp66GdIOyggOyepVxuICAgICAgICAgICAgY29uc3QgdGFibGUgPSB0aGlzLmJ1aWxkZXIuZ2V0VGFibGUodGFibGVOYW1lKTtcbiAgICAgICAgICAgIGNvbnN0IHV1aWRzID0gdGFibGUucm93cy5tYXAoKHJvdykgPT4gcm93LnV1aWQgYXMgc3RyaW5nKTtcblxuICAgICAgICAgICAgIWlzVGVzdCgpICYmXG4gICAgICAgICAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICAgICAgICAgIGNoYWxrLmJsdWUoXG4gICAgICAgICAgICAgICAgICBgVXBzZXJ0aW5nICR7dGFibGVOYW1lfSB3aXRoICR7dXVpZHMubGVuZ3RofSByb3dzIChsZXZlbCAke2xldmVscy5pbmRleE9mKGxldmVsRml4dHVyZXMpICsgMX0vJHtsZXZlbHMubGVuZ3RofSlgLFxuICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICBjb25zdCBpZHMgPSAoYXdhaXQgdGhpcy5idWlsZGVyLnVwc2VydChcbiAgICAgICAgICAgICAgdHJ4LFxuICAgICAgICAgICAgICB0YWJsZU5hbWUgYXMga2V5b2YgRGF0YWJhc2VTY2hlbWFFeHRlbmQsXG4gICAgICAgICAgICApKSBhcyAobnVtYmVyIHwgc3RyaW5nKVtdO1xuXG4gICAgICAgICAgICAvLyDsiJzshJwg6riw67CYIHV1aWQgLT4gaWQg66ek7ZWRXG4gICAgICAgICAgICAvLyBzZWxmLXJlZmVyZW5jZeqwgCDsl4bsnLzrr4DroZwg65Ox66GdIOyInOyEnCA9IOuwmO2ZmCDsiJzshJwg67O07J6lXG4gICAgICAgICAgICBpZiAodXVpZHMubGVuZ3RoID4gMCAmJiB1dWlkcy5sZW5ndGggPT09IGlkcy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgY29uc3QgZXhpc3RpbmdNYXAgPVxuICAgICAgICAgICAgICAgIGluc2VydGVkSWRzQnlUYWJsZS5nZXQodGFibGVOYW1lKSA/PyBuZXcgTWFwPHN0cmluZywgbnVtYmVyIHwgc3RyaW5nPigpO1xuICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHV1aWRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgZXhpc3RpbmdNYXAuc2V0KHV1aWRzW2ldLCBpZHNbaV0pO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGluc2VydGVkSWRzQnlUYWJsZS5zZXQodGFibGVOYW1lLCBleGlzdGluZ01hcCk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHV1aWRzLmxlbmd0aCAhPT0gaWRzLmxlbmd0aCkge1xuICAgICAgICAgICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgICAgICAgICAgY2hhbGsueWVsbG93KFxuICAgICAgICAgICAgICAgICAgYFdhcm5pbmc6IHV1aWQgY291bnQgKCR7dXVpZHMubGVuZ3RofSkgIT0gaWQgY291bnQgKCR7aWRzLmxlbmd0aH0pIGZvciAke3RhYmxlTmFtZX1gLFxuICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gNS4gTWFueVRvTWFueSDqtIDqs4Qg7LKY66asXG4gICAgICAgIGF3YWl0IHRoaXMucHJvY2Vzc01hbnlUb01hbnlSZWxhdGlvbnModHJ4LCBmaXh0dXJlcywgaW5zZXJ0ZWRJZHNCeVRhYmxlKTtcblxuICAgICAgICAvLyA2LiBQb3N0Z3JlU1FMIOyLnO2AgOyKpCDrpqzshYtcbiAgICAgICAgLy8gRml4dHVyZSDsgr3snoUg7ZuEIOqwgSDthYzsnbTruJTsnZggSUQg7Iuc7YCA7Iqk66W8IOy1nOuMgCBJRCDqsJLsnLzroZwg7JeF642w7J207Yq47ZWp64uI64ukLlxuICAgICAgICAvLyDsnbTroIfqsowg7ZWY7KeAIOyViuycvOuptCDri6TsnYwgSU5TRVJUIOyLnCBJROqwgCAyMDAw67KI64yA66GcIOyDneyEseuQoCDsiJgg7J6I7Iq164uI64ukLlxuICAgICAgICAhaXNUZXN0KCkgJiYgY29uc29sZS5sb2coY2hhbGsuYmx1ZShcIlJlc2V0dGluZyBzZXF1ZW5jZXMuLi5cIikpO1xuICAgICAgICBmb3IgKGNvbnN0IHRhYmxlTmFtZSBvZiB0YWJsZU9yZGVyKSB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIC8vIEVudGl0eeulvCDssL7slYTshJwgaWQg7YOA7J6FIO2ZleyduFxuICAgICAgICAgICAgY29uc3QgZW50aXR5ID0gRW50aXR5TWFuYWdlci5nZXRBbGxFbnRpdGllcygpLmZpbmQoXG4gICAgICAgICAgICAgIChlKSA9PiBlLnRhYmxlID09PSB0YWJsZU5hbWUgfHwgZS5pZC50b0xvd2VyQ2FzZSgpID09PSB0YWJsZU5hbWUsXG4gICAgICAgICAgICApO1xuXG4gICAgICAgICAgICBpZiAoZW50aXR5KSB7XG4gICAgICAgICAgICAgIGNvbnN0IGlkUHJvcCA9IGVudGl0eS5wcm9wcy5maW5kKChwKSA9PiBwLm5hbWUgPT09IFwiaWRcIik7XG4gICAgICAgICAgICAgIGNvbnN0IGlkVHlwZSA9IGlkUHJvcD8udHlwZTtcblxuICAgICAgICAgICAgICAvLyBpbnRlZ2VyL2JpZ0ludGVnZXLsnbTqsbDrgpgsIHN0cmluZ+ydtOyngOunjCBmaXh0dXJlU3RyYXRlZ3k9c2VxdWVuY2Xsnbgg6rK97Jqw7JeQ66eMIOumrOyFi+2VqeuLiOuLpFxuICAgICAgICAgICAgICBjb25zdCB1c2VzU2VxdWVuY2UgPVxuICAgICAgICAgICAgICAgIGlkVHlwZSA9PT0gXCJpbnRlZ2VyXCIgfHxcbiAgICAgICAgICAgICAgICBpZFR5cGUgPT09IFwiYmlnSW50ZWdlclwiIHx8XG4gICAgICAgICAgICAgICAgaWRQcm9wPy5jb25lPy5maXh0dXJlU3RyYXRlZ3kgPT09IFwic2VxdWVuY2VcIjtcblxuICAgICAgICAgICAgICBpZiAoIXVzZXNTZXF1ZW5jZSkge1xuICAgICAgICAgICAgICAgICFpc1Rlc3QoKSAmJlxuICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coXG4gICAgICAgICAgICAgICAgICAgIGNoYWxrLmdyYXkoXG4gICAgICAgICAgICAgICAgICAgICAgYFNraXBwZWQgc2VxdWVuY2UgcmVzZXQgZm9yICR7dGFibGVOYW1lfSAoaWQgdHlwZTogJHtpZFR5cGUgfHwgXCJ1bmtub3duXCJ9KWAsXG4gICAgICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIO2FjOydtOu4lOydmCDstZzrjIAgSUQg7KGw7ZqMIChzdHJpbmcg7YOA7J6F7J2AIOyIq+yekCDsupDsiqTtjIUg7ZWE7JqUKVxuICAgICAgICAgICAgY29uc3QgZW50aXR5MiA9IEVudGl0eU1hbmFnZXIuZ2V0QWxsRW50aXRpZXMoKS5maW5kKFxuICAgICAgICAgICAgICAoZSkgPT4gZS50YWJsZSA9PT0gdGFibGVOYW1lIHx8IGUuaWQudG9Mb3dlckNhc2UoKSA9PT0gdGFibGVOYW1lLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGNvbnN0IGlkVHlwZTIgPSBlbnRpdHkyPy5wcm9wcy5maW5kKChwKSA9PiBwLm5hbWUgPT09IFwiaWRcIik/LnR5cGU7XG4gICAgICAgICAgICBjb25zdCBtYXhJZFJlc3VsdCA9XG4gICAgICAgICAgICAgIGlkVHlwZTIgPT09IFwic3RyaW5nXCJcbiAgICAgICAgICAgICAgICA/IGF3YWl0IHRyeFxuICAgICAgICAgICAgICAgICAgICAucmF3KGBTRUxFQ1QgTUFYKGlkOjpiaWdpbnQpIGFzIG1heF9pZCBGUk9NIFwiJHt0YWJsZU5hbWV9XCJgKVxuICAgICAgICAgICAgICAgICAgICAudGhlbigocikgPT4gci5yb3dzWzBdKVxuICAgICAgICAgICAgICAgIDogYXdhaXQgdHJ4KHRhYmxlTmFtZSkubWF4KFwiaWQgYXMgbWF4X2lkXCIpLmZpcnN0KCk7XG4gICAgICAgICAgICBjb25zdCBtYXhJZCA9IG1heElkUmVzdWx0Py5tYXhfaWQ7XG5cbiAgICAgICAgICAgIGlmIChtYXhJZCAhPT0gbnVsbCAmJiBtYXhJZCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgIC8vIOyLnO2AgOyKpOuqheydhCBwZ19nZXRfc2VyaWFsX3NlcXVlbmNl66GcIOyViOyghO2VmOqyjCDsobDtmoxcbiAgICAgICAgICAgICAgYXdhaXQgdHJ4LnJhdyhgU0VMRUNUIHNldHZhbChwZ19nZXRfc2VyaWFsX3NlcXVlbmNlKD8sICdpZCcpLCA/KWAsIFtcbiAgICAgICAgICAgICAgICB0YWJsZU5hbWUsXG4gICAgICAgICAgICAgICAgbWF4SWQsXG4gICAgICAgICAgICAgIF0pO1xuICAgICAgICAgICAgICAhaXNUZXN0KCkgJiYgY29uc29sZS5sb2coY2hhbGsuZ3JlZW4oYFJlc2V0IHNlcXVlbmNlIGZvciAke3RhYmxlTmFtZX06ICR7bWF4SWR9YCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gY2F0Y2gge1xuICAgICAgICAgICAgLy8g7Iuc7YCA7Iqk6rCAIOyXhuuKlCDthYzsnbTruJQoam9pbiB0YWJsZSDrk7Ep7J2AIOustOyLnFxuICAgICAgICAgICAgIWlzVGVzdCgpICYmIGNvbnNvbGUubG9nKGNoYWxrLmdyYXkoYFNraXBwZWQgc2VxdWVuY2UgcmVzZXQgZm9yICR7dGFibGVOYW1lfWApKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyA3LiDqsrDqs7wg7IiY7KeRXG4gICAgICAgIGZvciAoY29uc3QgZml4dHVyZSBvZiBmaXh0dXJlcykge1xuICAgICAgICAgIGNvbnN0IGVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0KGZpeHR1cmUuZW50aXR5SWQpO1xuXG4gICAgICAgICAgLy8g7Iqk7YK165CcIGZpeHR1cmXripQg6riw7KG0IOugiOy9lOuTnCDsoJXrs7TroZwg6rKw6rO8IOy2lOqwgFxuICAgICAgICAgIGNvbnN0IHNraXBwZWQgPSB0aGlzLnNraXBwZWRGaXh0dXJlcy5nZXQoZml4dHVyZS5maXh0dXJlSWQpO1xuICAgICAgICAgIGlmIChza2lwcGVkKSB7XG4gICAgICAgICAgICByZXN1bHRzLnB1c2goe1xuICAgICAgICAgICAgICBlbnRpdHlJZDogZml4dHVyZS5lbnRpdHlJZCxcbiAgICAgICAgICAgICAgZGF0YTogYXdhaXQgdHJ4KGVudGl0eS50YWJsZSkud2hlcmUoXCJpZFwiLCBza2lwcGVkLmV4aXN0aW5nSWQpLmZpcnN0KCksXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnN0IHJlZiA9IHRoaXMuZml4dHVyZVJlZk1hcC5nZXQoZml4dHVyZS5maXh0dXJlSWQpO1xuICAgICAgICAgIGlmIChyZWYpIHtcbiAgICAgICAgICAgIGNvbnN0IHV1aWRUb0lkID0gaW5zZXJ0ZWRJZHNCeVRhYmxlLmdldChlbnRpdHkudGFibGUpO1xuICAgICAgICAgICAgY29uc3QgaW5zZXJ0ZWRJZCA9IHV1aWRUb0lkPy5nZXQocmVmLnV1aWQpO1xuXG4gICAgICAgICAgICBpZiAoaW5zZXJ0ZWRJZCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgIHJlc3VsdHMucHVzaCh7XG4gICAgICAgICAgICAgICAgZW50aXR5SWQ6IGZpeHR1cmUuZW50aXR5SWQsXG4gICAgICAgICAgICAgICAgZGF0YTogYXdhaXQgdHJ4KGVudGl0eS50YWJsZSkud2hlcmUoXCJpZFwiLCBpbnNlcnRlZElkKS5maXJzdCgpLFxuICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAhaXNUZXN0KCkgJiZcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgICAgICAgICAgIGNoYWxrLmdyZWVuKGBJbnNlcnRlZCBpbnRvICR7ZW50aXR5LnRhYmxlfTogIyR7Zml4dHVyZS5pZH0gLT4gIyR7aW5zZXJ0ZWRJZH1gKSxcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIGF3YWl0IGRiLmRlc3Ryb3koKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdW5pcXVlKHJlc3VsdHMsIChyKSA9PiBgJHtyLmVudGl0eUlkfSMke3IuZGF0YS5pZH1gKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGaXh0dXJlUmVjb3Jk66W8IFVwc2VydEJ1aWxkZXLsl5Ag65Ox66GdXG4gICAqIEBwYXJhbSBpbnNlcnRlZElkc0J5VGFibGUg7J2066+4IHVwc2VydOuQnCDthYzsnbTruJTsnZggdXVpZOKGkmlkIOunpO2VkSAo66CI67Ko67OEIOyymOumrCDsi5wg7IKs7JqpKVxuICAgKi9cbiAgcHJpdmF0ZSByZWdpc3RlckZpeHR1cmUoXG4gICAgZml4dHVyZTogRml4dHVyZVJlY29yZCxcbiAgICBpbnNlcnRlZElkc0J5VGFibGU/OiBNYXA8c3RyaW5nLCBNYXA8c3RyaW5nLCBudW1iZXIgfCBzdHJpbmc+PixcbiAgKTogVUJSZWYge1xuICAgIGNvbnN0IGVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0KGZpeHR1cmUuZW50aXR5SWQpO1xuICAgIGNvbnN0IHJvdzogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPSB7fTtcblxuICAgIC8vIE92ZXJyaWRlIOuqqOuTnCDtjJDri6g6IHRhcmdldCDrmJDripQgdW5pcXVl6rCAIOyeiOqzoCBvdmVycmlkZT10cnVl7J24IOqyveyasFxuICAgIGNvbnN0IGV4aXN0aW5nUmVjb3JkID0gZml4dHVyZS50YXJnZXQgPz8gZml4dHVyZS51bmlxdWU7XG4gICAgY29uc3QgaXNPdmVycmlkZU1vZGUgPSBmaXh0dXJlLm92ZXJyaWRlICYmIGV4aXN0aW5nUmVjb3JkO1xuXG4gICAgZm9yIChjb25zdCBbcHJvcE5hbWUsIGNvbHVtbl0gb2YgT2JqZWN0LmVudHJpZXMoZml4dHVyZS5jb2x1bW5zKSkge1xuICAgICAgY29uc3QgcHJvcCA9IGNvbHVtbi5wcm9wO1xuXG4gICAgICBpZiAoaXNWaXJ0dWFsUHJvcChwcm9wKSkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgLy8gR2VuZXJhdGVkIGNvbHVtbuydgCBJTlNFUlTsl5DshJwg7KCc7Jm4IChEQuqwgCDsnpDrj5kg7IOd7ISxKVxuICAgICAgaWYgKFwiZ2VuZXJhdGVkXCIgaW4gcHJvcCAmJiBwcm9wLmdlbmVyYXRlZCkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgLy8gaWQg7LKY66asXG4gICAgICBpZiAocHJvcE5hbWUgPT09IFwiaWRcIikge1xuICAgICAgICBjb25zdCBpZFByb3AgPSBlbnRpdHkucHJvcHMuZmluZCgocCkgPT4gcC5uYW1lID09PSBcImlkXCIpO1xuICAgICAgICAvLyBwYXJlbnRJZCDsl5Tti7Dti7DsnZggaWTripQg67aA66qoIOyXlO2LsO2LsOydmCBGS+ydtOuvgOuhnCDsi5ztgIDsiqQg66+47IKs7JqpICjrqoXsi5zsoIHsnLzroZwg7Y+s7ZWoKVxuICAgICAgICBjb25zdCB1c2VzU2VxdWVuY2UgPVxuICAgICAgICAgICFlbnRpdHkucGFyZW50SWQgJiZcbiAgICAgICAgICAoaWRQcm9wPy50eXBlID09PSBcImludGVnZXJcIiB8fFxuICAgICAgICAgICAgaWRQcm9wPy50eXBlID09PSBcImJpZ0ludGVnZXJcIiB8fFxuICAgICAgICAgICAgaWRQcm9wPy5jb25lPy5maXh0dXJlU3RyYXRlZ3kgPT09IFwic2VxdWVuY2VcIik7XG5cbiAgICAgICAgaWYgKGlzT3ZlcnJpZGVNb2RlICYmIGV4aXN0aW5nUmVjb3JkKSB7XG4gICAgICAgICAgLy8gT3ZlcnJpZGU6IOq4sOyhtCDroIjsvZTrk5zsnZgg6rCSIOyCrOyaqSDihpIgVVBEQVRFXG4gICAgICAgICAgcm93W3Byb3BOYW1lXSA9IGV4aXN0aW5nUmVjb3JkLmNvbHVtbnNbcHJvcE5hbWVdPy52YWx1ZTtcbiAgICAgICAgfSBlbHNlIGlmICghdXNlc1NlcXVlbmNlKSB7XG4gICAgICAgICAgLy8gc3RyaW5nIFBLIOuYkOuKlCBwYXJlbnRJZCDsl5Tti7Dti7AgRks6IOyDneyEseuQnCBpZCDqsJLsnYQgSU5TRVJU7JeQIO2PrO2VqFxuICAgICAgICAgIHJvd1twcm9wTmFtZV0gPSBjb2x1bW4udmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgLy8gaW50ZWdlci9iaWdJbnRlZ2VyIFBLOiBEQiDsi5ztgIDsiqTsl5Ag66eh6rmAICjqsJIg7KCc7Jm4KVxuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKGlzUmVsYXRpb25Qcm9wKHByb3ApKSB7XG4gICAgICAgIGlmIChcbiAgICAgICAgICBpc0JlbG9uZ3NUb09uZVJlbGF0aW9uUHJvcChwcm9wKSB8fFxuICAgICAgICAgIChpc09uZVRvT25lUmVsYXRpb25Qcm9wKHByb3ApICYmIHByb3AuaGFzSm9pbkNvbHVtbilcbiAgICAgICAgKSB7XG4gICAgICAgICAgY29uc3QgcmVsYXRlZElkID0gY29sdW1uLnZhbHVlIGFzIG51bWJlciB8IG51bGw7XG4gICAgICAgICAgaWYgKHJlbGF0ZWRJZCAhPT0gbnVsbCAmJiByZWxhdGVkSWQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgY29uc3QgcmVsYXRlZEZpeHR1cmVJZCA9IGAke3Byb3Aud2l0aH0jJHtyZWxhdGVkSWR9YDtcblxuICAgICAgICAgICAgLy8g66i87KCAIHNraXDrkJwgZml4dHVyZeyduOyngCDtmZXsnbhcbiAgICAgICAgICAgIGNvbnN0IHNraXBwZWRFeGlzdGluZ0lkID0gdGhpcy5za2lwcGVkRml4dHVyZXMuZ2V0KHJlbGF0ZWRGaXh0dXJlSWQpPy5leGlzdGluZ0lkO1xuICAgICAgICAgICAgaWYgKHNraXBwZWRFeGlzdGluZ0lkICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgLy8gc2tpcOuQnCBmaXh0dXJlIOKGkiB0YXJnZXQgRELsnZgg6riw7KG0IOugiOy9lOuTnCBpZCDsgqzsmqlcbiAgICAgICAgICAgICAgcm93W2Ake3Byb3BOYW1lfV9pZGBdID0gc2tpcHBlZEV4aXN0aW5nSWQ7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBjb25zdCByZWxhdGVkUmVmID0gdGhpcy5maXh0dXJlUmVmTWFwLmdldChyZWxhdGVkRml4dHVyZUlkKTtcbiAgICAgICAgICAgICAgaWYgKHJlbGF0ZWRSZWYpIHtcbiAgICAgICAgICAgICAgICAvLyDsnbTrr7ggdXBzZXJ065CcIOqwmeydgCDthYzsnbTruJQgZml4dHVyZSDtmZXsnbhcbiAgICAgICAgICAgICAgICBjb25zdCByZWxhdGVkRW50aXR5ID0gRW50aXR5TWFuYWdlci5nZXQocHJvcC53aXRoKTtcbiAgICAgICAgICAgICAgICBjb25zdCByZWxhdGVkSW5zZXJ0ZWRJZHMgPSBpbnNlcnRlZElkc0J5VGFibGU/LmdldChyZWxhdGVkRW50aXR5LnRhYmxlKTtcbiAgICAgICAgICAgICAgICBjb25zdCBhY3R1YWxJZCA9IHJlbGF0ZWRJbnNlcnRlZElkcz8uZ2V0KHJlbGF0ZWRSZWYudXVpZCk7XG5cbiAgICAgICAgICAgICAgICBpZiAoYWN0dWFsSWQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgLy8g7J2066+4IHVwc2VydOuQqCDihpIg7Iuk7KCcIElEIOyCrOyaqVxuICAgICAgICAgICAgICAgICAgcm93W2Ake3Byb3BOYW1lfV9pZGBdID0gYWN0dWFsSWQ7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgIC8vIOyVhOyngSB1cHNlcnQg7JWI65CoIOKGkiBVQlJlZiDsgqzsmqlcbiAgICAgICAgICAgICAgICAgIHJvd1tgJHtwcm9wTmFtZX1faWRgXSA9IHJlbGF0ZWRSZWY7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIGZpeHR1cmVz7JeQIO2PrO2VqOuQmOyngCDslYrsnYAg66CI7L2U65OcIOKGkiBJRCDqt7jrjIDroZwg7IKs7JqpXG4gICAgICAgICAgICAgICAgcm93W2Ake3Byb3BOYW1lfV9pZGBdID0gcmVsYXRlZElkO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJvd1tgJHtwcm9wTmFtZX1faWRgXSA9IG51bGw7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vIEhhc01hbnksIE1hbnlUb01hbnnripQg67OE64+EIOyymOumrFxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8g7J2867CYIOy7rOufvFxuICAgICAgICByb3dbcHJvcE5hbWVdID0gdGhpcy5jb252ZXJ0Q29sdW1uVmFsdWUocHJvcCBhcyBFbnRpdHlQcm9wLCBjb2x1bW4udmFsdWUpO1xuICAgICAgfVxuICAgIH1cblxuICAgICFpc1Rlc3QoKSAmJlxuICAgICAgY29uc29sZS5sb2coY2hhbGsuYmx1ZShgUmVnaXN0ZXJpbmcgJHtlbnRpdHkudGFibGV9IC0gJHtpbnNwZWN0KHJvdywgZmFsc2UsIG51bGwsIHRydWUpfWApKTtcbiAgICBjb25zdCByZWYgPSB0aGlzLmJ1aWxkZXIucmVnaXN0ZXIoZW50aXR5LnRhYmxlLCByb3cpO1xuICAgIHRoaXMuZml4dHVyZVJlZk1hcC5zZXQoZml4dHVyZS5maXh0dXJlSWQsIHJlZik7XG5cbiAgICByZXR1cm4gcmVmO1xuICB9XG5cbiAgLyoqXG4gICAqIOy7rOufvCDqsJIg67OA7ZmYXG4gICAqL1xuICBwcml2YXRlIGNvbnZlcnRDb2x1bW5WYWx1ZShwcm9wOiBFbnRpdHlQcm9wLCB2YWx1ZTogdW5rbm93bik6IHVua25vd24ge1xuICAgIGlmICh2YWx1ZSA9PT0gbnVsbCB8fCB2YWx1ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBzd2l0Y2ggKHByb3AudHlwZSkge1xuICAgICAgY2FzZSBcImpzb25cIjpcbiAgICAgICAgLy8gVXBzZXJ0QnVpbGRlci5yZWdpc3RlcuyXkOyEnCBKU09OLnN0cmluZ2lmeSDsspjrpqztlZjrr4DroZwgb2JqZWN0IOq3uOuMgOuhnCDsoITri6xcbiAgICAgICAgcmV0dXJuIHZhbHVlO1xuXG4gICAgICBjYXNlIFwiZGF0ZVwiOlxuICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSBcInN0cmluZ1wiIHx8IHR5cGVvZiB2YWx1ZSA9PT0gXCJudW1iZXJcIikge1xuICAgICAgICAgIHJldHVybiBuZXcgRGF0ZSh2YWx1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHZhbHVlO1xuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBwcm9jZXNzTWFueVRvTWFueVJlbGF0aW9ucyhcbiAgICB0cng6IEtuZXguVHJhbnNhY3Rpb24sXG4gICAgZml4dHVyZXM6IEZpeHR1cmVSZWNvcmRbXSxcbiAgICBpbnNlcnRlZElkc0J5VGFibGU6IE1hcDxzdHJpbmcsIE1hcDxzdHJpbmcsIG51bWJlciB8IHN0cmluZz4+LFxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBmb3IgKGNvbnN0IGZpeHR1cmUgb2YgZml4dHVyZXMpIHtcbiAgICAgIGNvbnN0IGVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0KGZpeHR1cmUuZW50aXR5SWQpO1xuICAgICAgY29uc3Qgc291cmNlUmVmID0gdGhpcy5maXh0dXJlUmVmTWFwLmdldChmaXh0dXJlLmZpeHR1cmVJZCk7XG5cbiAgICAgIGlmICghc291cmNlUmVmKSBjb250aW51ZTtcblxuICAgICAgY29uc3Qgc291cmNlVXVpZFRvSWQgPSBpbnNlcnRlZElkc0J5VGFibGUuZ2V0KGVudGl0eS50YWJsZSk7XG4gICAgICBjb25zdCBzb3VyY2VJZCA9IHNvdXJjZVV1aWRUb0lkPy5nZXQoc291cmNlUmVmLnV1aWQpO1xuXG4gICAgICBpZiAoc291cmNlSWQgPT09IHVuZGVmaW5lZCkgY29udGludWU7XG5cbiAgICAgIGZvciAoY29uc3QgWywgY29sdW1uXSBvZiBPYmplY3QuZW50cmllcyhmaXh0dXJlLmNvbHVtbnMpKSB7XG4gICAgICAgIGNvbnN0IHByb3AgPSBjb2x1bW4ucHJvcDtcblxuICAgICAgICBpZiAoaXNNYW55VG9NYW55UmVsYXRpb25Qcm9wKHByb3ApICYmIEFycmF5LmlzQXJyYXkoY29sdW1uLnZhbHVlKSkge1xuICAgICAgICAgIC8vIOyEoO2DneuQmOyngCDslYrsnYAgTWFueVRvTWFueSDqtIDqs4TripQg7KCA7J6l7ZWY7KeAIOyViuydjFxuICAgICAgICAgIGNvbnN0IHRhcmdldFRhYmxlID0gRW50aXR5TWFuYWdlci5nZXQocHJvcC53aXRoKTtcbiAgICAgICAgICBpZiAoIXRoaXMuYnVpbGRlci5oYXNUYWJsZSh0YXJnZXRUYWJsZS50YWJsZSkpIGNvbnRpbnVlO1xuXG4gICAgICAgICAgY29uc3QgcmVsYXRlZElkcyA9IGNvbHVtbi52YWx1ZSBhcyBudW1iZXJbXTtcbiAgICAgICAgICBpZiAocmVsYXRlZElkcy5sZW5ndGggPT09IDApIGNvbnRpbnVlO1xuXG4gICAgICAgICAgY29uc3Qgam9pblRhYmxlID0gcHJvcC5qb2luVGFibGU7XG4gICAgICAgICAgY29uc3QgcmVsYXRlZEVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0KHByb3Aud2l0aCk7XG5cbiAgICAgICAgICBjb25zdCBzb3VyY2VDb2x1bW4gPSBgJHtpbmZsZWN0aW9uLnNpbmd1bGFyaXplKGVudGl0eS50YWJsZSl9X2lkYDtcbiAgICAgICAgICBjb25zdCB0YXJnZXRDb2x1bW4gPSBgJHtpbmZsZWN0aW9uLnNpbmd1bGFyaXplKHJlbGF0ZWRFbnRpdHkudGFibGUpfV9pZGA7XG5cbiAgICAgICAgICBmb3IgKGNvbnN0IHJlbGF0ZWRJZCBvZiByZWxhdGVkSWRzKSB7XG4gICAgICAgICAgICBjb25zdCByZWxhdGVkRml4dHVyZUlkID0gYCR7cHJvcC53aXRofSMke3JlbGF0ZWRJZH1gO1xuICAgICAgICAgICAgY29uc3QgcmVsYXRlZFJlZiA9IHRoaXMuZml4dHVyZVJlZk1hcC5nZXQocmVsYXRlZEZpeHR1cmVJZCk7XG5cbiAgICAgICAgICAgIGxldCB0YXJnZXRJZDogbnVtYmVyIHwgc3RyaW5nO1xuXG4gICAgICAgICAgICBpZiAocmVsYXRlZFJlZikge1xuICAgICAgICAgICAgICBjb25zdCByZWxhdGVkVXVpZFRvSWQgPSBpbnNlcnRlZElkc0J5VGFibGUuZ2V0KHJlbGF0ZWRFbnRpdHkudGFibGUpO1xuICAgICAgICAgICAgICBjb25zdCByZXNvbHZlZElkID0gcmVsYXRlZFV1aWRUb0lkPy5nZXQocmVsYXRlZFJlZi51dWlkKTtcblxuICAgICAgICAgICAgICBpZiAocmVzb2x2ZWRJZCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICAgICAgICAgICAgYFJlbGF0ZWQgZml4dHVyZSAke3JlbGF0ZWRGaXh0dXJlSWR9IG5vdCBmb3VuZCBpbiBpbnNlcnRlZElkcywgc2tpcHBpbmdgLFxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgdGFyZ2V0SWQgPSByZXNvbHZlZElkO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgdGFyZ2V0SWQgPSByZWxhdGVkSWQ7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIEpvaW5UYWJsZeyXkCDsgr3snoVcbiAgICAgICAgICAgIGNvbnN0IFtmb3VuZF0gPSBhd2FpdCB0cngoam9pblRhYmxlKVxuICAgICAgICAgICAgICAud2hlcmUoe1xuICAgICAgICAgICAgICAgIFtzb3VyY2VDb2x1bW5dOiBzb3VyY2VJZCxcbiAgICAgICAgICAgICAgICBbdGFyZ2V0Q29sdW1uXTogdGFyZ2V0SWQsXG4gICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgIC5saW1pdCgxKTtcblxuICAgICAgICAgICAgaWYgKCFmb3VuZCkge1xuICAgICAgICAgICAgICBhd2FpdCB0cngoam9pblRhYmxlKS5pbnNlcnQoe1xuICAgICAgICAgICAgICAgIFtzb3VyY2VDb2x1bW5dOiBzb3VyY2VJZCxcbiAgICAgICAgICAgICAgICBbdGFyZ2V0Q29sdW1uXTogdGFyZ2V0SWQsXG4gICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICFpc1Rlc3QoKSAmJlxuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICAgICAgICAgICAgY2hhbGsuZ3JlZW4oXG4gICAgICAgICAgICAgICAgICAgIGBJbnNlcnRlZCBpbnRvICR7am9pblRhYmxlfTogJHtlbnRpdHkudGFibGV9KCR7c291cmNlSWR9KSAtICR7cmVsYXRlZEVudGl0eS50YWJsZX0oJHt0YXJnZXRJZH0pYCxcbiAgICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICog6rCZ7J2AIO2FjOydtOu4lCDrgrQgZml4dHVyZeuTpOydhCBzZWxmLXJlZmVyZW5jZSDroIjrsqjrs4TroZwg67aE7ZWgXG4gICAqIC0gc2VsZi1yZWZlcmVuY2XqsIAg7JeG64qUIGZpeHR1cmXrk6Q6IExldmVsIDBcbiAgICogLSBMZXZlbCAw7J2EIOywuOyhsO2VmOuKlCBmaXh0dXJl65OkOiBMZXZlbCAxXG4gICAqIC0g67CY67O1XG4gICAqXG4gICAqIFVwc2VydEJ1aWxkZXLqsIAgc2VsZi1yZWZlcmVuY2XqsIAg7J6I7Jy866m0IGJ1aWxkSW5zZXJ0TGV2ZWxzKCnroZwg7J6s7KCV66Cs7ZWY7JesXG4gICAqIOuTseuhnSDsiJzshJzsmYAg67CY7ZmYIOyInOyEnOqwgCDri6zrnbzsp4gg7IiYIOyeiOyKteuLiOuLpC5cbiAgICog7J2066W8IOuwqeyngO2VmOq4sCDsnITtlbQgRml4dHVyZU1hbmFnZXLqsIAg66CI67Ko67OE66GcIOuCmOuIoOyEnCDsspjrpqztlanri4jri6QuXG4gICAqL1xuICBwcml2YXRlIGdyb3VwRml4dHVyZXNCeUxldmVsKGZpeHR1cmVzOiBGaXh0dXJlUmVjb3JkW10pOiBGaXh0dXJlUmVjb3JkW11bXSB7XG4gICAgaWYgKGZpeHR1cmVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIFtdO1xuICAgIH1cblxuICAgIGNvbnN0IGVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0KGZpeHR1cmVzWzBdLmVudGl0eUlkKTtcblxuICAgIC8vIHNlbGYtcmVmZXJlbmNlIHJlbGF0aW9uIHByb3Ag7LC+6riwXG4gICAgY29uc3Qgc2VsZlJlZlByb3BzID0gZW50aXR5LnByb3BzLmZpbHRlcihcbiAgICAgIChwKTogcCBpcyBCZWxvbmdzVG9PbmVSZWxhdGlvblByb3AgfCBPbmVUb09uZVJlbGF0aW9uUHJvcCA9PlxuICAgICAgICBpc1JlbGF0aW9uUHJvcChwKSAmJlxuICAgICAgICAoaXNCZWxvbmdzVG9PbmVSZWxhdGlvblByb3AocCkgfHwgKGlzT25lVG9PbmVSZWxhdGlvblByb3AocCkgJiYgcC5oYXNKb2luQ29sdW1uKSkgJiZcbiAgICAgICAgcC53aXRoID09PSBlbnRpdHkuaWQsXG4gICAgKTtcblxuICAgIGlmIChzZWxmUmVmUHJvcHMubGVuZ3RoID09PSAwKSB7XG4gICAgICAvLyBzZWxmLXJlZmVyZW5jZSDsl4bsnYwg4oaSIOuLqOydvCDroIjrsqhcbiAgICAgIHJldHVybiBbZml4dHVyZXNdO1xuICAgIH1cblxuICAgIC8vIOugiOuyqOuzhCDrtoTtlaAgKHRvcG9sb2dpY2FsIHNvcnQpXG4gICAgY29uc3QgbGV2ZWxzOiBGaXh0dXJlUmVjb3JkW11bXSA9IFtdO1xuICAgIGNvbnN0IHJlbWFpbmluZyA9IG5ldyBTZXQoZml4dHVyZXMubWFwKChmKSA9PiBmLmZpeHR1cmVJZCkpO1xuICAgIGNvbnN0IHByb2Nlc3NlZCA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuXG4gICAgd2hpbGUgKHJlbWFpbmluZy5zaXplID4gMCkge1xuICAgICAgY29uc3QgY3VycmVudExldmVsOiBGaXh0dXJlUmVjb3JkW10gPSBbXTtcblxuICAgICAgZm9yIChjb25zdCBmaXh0dXJlIG9mIGZpeHR1cmVzKSB7XG4gICAgICAgIGlmICghcmVtYWluaW5nLmhhcyhmaXh0dXJlLmZpeHR1cmVJZCkpIGNvbnRpbnVlO1xuXG4gICAgICAgIC8vIHNlbGYtcmVmZXJlbmNl6rCAIOuqqOuRkCDsnbTrr7gg7LKY66as65CQ6rGw64KYIG51bGzsnbgg6rK97JqwXG4gICAgICAgIGNvbnN0IGNhblByb2Nlc3MgPSBzZWxmUmVmUHJvcHMuZXZlcnkoKHByb3ApID0+IHtcbiAgICAgICAgICBjb25zdCByZWZJZCA9IGZpeHR1cmUuY29sdW1uc1twcm9wLm5hbWVdPy52YWx1ZSBhcyBudW1iZXIgfCBudWxsO1xuICAgICAgICAgIGlmIChyZWZJZCA9PT0gbnVsbCB8fCByZWZJZCA9PT0gdW5kZWZpbmVkKSByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICBjb25zdCByZWZGaXh0dXJlSWQgPSBgJHtwcm9wLndpdGh9IyR7cmVmSWR9YDtcbiAgICAgICAgICAvLyDsnbTrr7gg7LKY66as65CQ6rGw64KYLCDtmITsnqwgZml4dHVyZXPsl5Ag7Y+s7ZWo65CY7KeAIOyViuydgCDqsr3smrAgKOyZuOu2gCDssLjsobApXG4gICAgICAgICAgcmV0dXJuIHByb2Nlc3NlZC5oYXMocmVmRml4dHVyZUlkKSB8fCAhcmVtYWluaW5nLmhhcyhyZWZGaXh0dXJlSWQpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpZiAoY2FuUHJvY2Vzcykge1xuICAgICAgICAgIGN1cnJlbnRMZXZlbC5wdXNoKGZpeHR1cmUpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChjdXJyZW50TGV2ZWwubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIGNvbnN0IHJlbWFpbmluZ0lkcyA9IEFycmF5LmZyb20ocmVtYWluaW5nKS5qb2luKFwiLCBcIik7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICBgQ2lyY3VsYXIgc2VsZi1yZWZlcmVuY2UgZGV0ZWN0ZWQgaW4gJHtlbnRpdHkudGFibGV9LiBSZW1haW5pbmcgZml4dHVyZXM6ICR7cmVtYWluaW5nSWRzfWAsXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIGZvciAoY29uc3QgZml4dHVyZSBvZiBjdXJyZW50TGV2ZWwpIHtcbiAgICAgICAgcmVtYWluaW5nLmRlbGV0ZShmaXh0dXJlLmZpeHR1cmVJZCk7XG4gICAgICAgIHByb2Nlc3NlZC5hZGQoZml4dHVyZS5maXh0dXJlSWQpO1xuICAgICAgfVxuXG4gICAgICBsZXZlbHMucHVzaChjdXJyZW50TGV2ZWwpO1xuICAgIH1cblxuICAgIHJldHVybiBsZXZlbHM7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGNoZWNrVW5pcXVlVmlvbGF0aW9uKGRiOiBLbmV4LCBlbnRpdHk6IEVudGl0eSwgZml4dHVyZTogRml4dHVyZVJlY29yZCkge1xuICAgIGNvbnN0IF91bmlxdWVJbmRleGVzID0gZW50aXR5LmluZGV4ZXM/LmZpbHRlcigoaSkgPT4gaS50eXBlID09PSBcInVuaXF1ZVwiKSA/PyBbXTtcblxuICAgIGNvbnN0IHVuaXF1ZUluZGV4ZXMgPSBfdW5pcXVlSW5kZXhlcy5maWx0ZXIoKGluZGV4KSA9PlxuICAgICAgaW5kZXguY29sdW1ucy5ldmVyeSgoY29sdW1uKSA9PiAhY29sdW1uLm5hbWUuc3RhcnRzV2l0aChgJHtlbnRpdHkudGFibGV9X19gKSksXG4gICAgKTtcbiAgICBpZiAodW5pcXVlSW5kZXhlcy5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIGxldCB1bmlxdWVRdWVyeSA9IGRiKGVudGl0eS50YWJsZSk7XG4gICAgbGV0IGhhc0NvbmRpdGlvbiA9IGZhbHNlO1xuXG4gICAgZm9yIChjb25zdCBpbmRleCBvZiB1bmlxdWVJbmRleGVzKSB7XG4gICAgICAvLyDsu6zrn7wg7KSRIO2VmOuCmOudvOuPhCBudWxs7J2066m0IOycoOuLiO2BrCDsoJzslb3snYQg7JyE67CY7ZWY7KeAIOyViuq4sCDrlYzrrLjsl5Ag7ZW064u5IOyduOuNseyKpOuKlCDrrLTsi5xcbiAgICAgIGNvbnN0IGNvbnRhaW5zTnVsbCA9IGluZGV4LmNvbHVtbnMuc29tZSgoY29sdW1uKSA9PiB7XG4gICAgICAgIGNvbnN0IGZpZWxkID0gY29sdW1uLm5hbWUucmVwbGFjZSgvX2lkJC8sIFwiXCIpO1xuICAgICAgICByZXR1cm4gZml4dHVyZS5jb2x1bW5zW2ZpZWxkXT8udmFsdWUgPT09IG51bGw7XG4gICAgICB9KTtcbiAgICAgIGlmIChjb250YWluc051bGwpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIHVuaXF1ZVF1ZXJ5ID0gdW5pcXVlUXVlcnkub3JXaGVyZSgocWIpID0+IHtcbiAgICAgICAgZm9yIChjb25zdCBjb2x1bW4gb2YgaW5kZXguY29sdW1ucykge1xuICAgICAgICAgIGNvbnN0IGZpZWxkID0gY29sdW1uLm5hbWUucmVwbGFjZSgvX2lkJC8sIFwiXCIpO1xuXG4gICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoZml4dHVyZS5jb2x1bW5zW2ZpZWxkXT8udmFsdWUpKSB7XG4gICAgICAgICAgICBxYi53aGVyZUluKGNvbHVtbi5uYW1lLCBmaXh0dXJlLmNvbHVtbnNbZmllbGRdLnZhbHVlKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcWIuYW5kV2hlcmUoY29sdW1uLm5hbWUsIGZpeHR1cmUuY29sdW1uc1tmaWVsZF0/LnZhbHVlKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgaGFzQ29uZGl0aW9uID0gdHJ1ZTtcbiAgICB9XG5cbiAgICBpZiAoIWhhc0NvbmRpdGlvbikge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgY29uc3QgW3VuaXF1ZUZvdW5kXSA9IGF3YWl0IHVuaXF1ZVF1ZXJ5O1xuICAgIHJldHVybiB1bmlxdWVGb3VuZDtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgY2hlY2tEdXBsaWNhdGVCeUNvbHVtbnMoXG4gICAgZGI6IEtuZXgsXG4gICAgZW50aXR5OiBFbnRpdHksXG4gICAgZml4dHVyZTogRml4dHVyZVJlY29yZCxcbiAgICBjb2x1bW5zOiBzdHJpbmdbXSxcbiAgKSB7XG4gICAgaWYgKGNvbHVtbnMubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBjb25zdCB3aGVyZUNsYXVzZTogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPSB7fTtcblxuICAgIGZvciAoY29uc3QgY29sdW1uIG9mIGNvbHVtbnMpIHtcbiAgICAgIC8vIHJlbGF0aW9uIO2VhOuTnOyduCDqsr3smrAgX2lkIOu2meydtOq4sFxuICAgICAgY29uc3QgcHJvcCA9IGVudGl0eS5wcm9wcy5maW5kKChwKSA9PiBwLm5hbWUgPT09IGNvbHVtbik7XG4gICAgICBjb25zdCBkYkNvbHVtbiA9IHByb3AgJiYgaXNSZWxhdGlvblByb3AocHJvcCkgPyBgJHtjb2x1bW59X2lkYCA6IGNvbHVtbjtcbiAgICAgIGNvbnN0IHZhbHVlID0gZml4dHVyZS5jb2x1bW5zW2NvbHVtbl0/LnZhbHVlO1xuXG4gICAgICAvLyBudWxsIOqwkuydtCDtj6ztlajrkJwg6rK97JqwIOykkeuztSDtmZXsnbgg7Iqk7YK1XG4gICAgICBpZiAodmFsdWUgPT09IG51bGwgfHwgdmFsdWUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cblxuICAgICAgd2hlcmVDbGF1c2VbZGJDb2x1bW5dID0gdmFsdWU7XG4gICAgfVxuXG4gICAgY29uc3QgW2ZvdW5kXSA9IGF3YWl0IGRiKGVudGl0eS50YWJsZSkud2hlcmUod2hlcmVDbGF1c2UpLmxpbWl0KDEpO1xuICAgIHJldHVybiBmb3VuZDtcbiAgfVxuXG4gIGFzeW5jIGFkZEZpeHR1cmVMb2FkZXIoY29kZTogc3RyaW5nKSB7XG4gICAgY29uc3QgcGF0aCA9IGAke1NvbmFtdS5hcGlSb290UGF0aH0vc3JjL3Rlc3RpbmcvZml4dHVyZS50c2A7XG4gICAgY29uc3QgY29udGVudCA9IHJlYWRGaWxlU3luYyhwYXRoKS50b1N0cmluZygpO1xuXG4gICAgY29uc3QgZml4dHVyZUxvYWRlclN0YXJ0ID0gY29udGVudC5pbmRleE9mKFwiY29uc3QgZml4dHVyZUxvYWRlciA9IHtcIik7XG4gICAgY29uc3QgZml4dHVyZUxvYWRlckVuZCA9IGNvbnRlbnQuaW5kZXhPZihcIn07XCIsIGZpeHR1cmVMb2FkZXJTdGFydCk7XG5cbiAgICBpZiAoZml4dHVyZUxvYWRlclN0YXJ0ICE9PSAtMSAmJiBmaXh0dXJlTG9hZGVyRW5kICE9PSAtMSkge1xuICAgICAgY29uc3QgbmV3Q29udGVudCA9IGAke2NvbnRlbnQuc2xpY2UoMCwgZml4dHVyZUxvYWRlckVuZCl9ICAke2NvZGV9XFxuJHtjb250ZW50LnNsaWNlKGZpeHR1cmVMb2FkZXJFbmQpfWA7XG5cbiAgICAgIHdyaXRlRmlsZVN5bmMocGF0aCwgbmV3Q29udGVudCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkZhaWxlZCB0byBmaW5kIGZpeHR1cmVMb2FkZXIgaW4gZml4dHVyZS50c1wiKTtcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IEZpeHR1cmVNYW5hZ2VyID0gbmV3IEZpeHR1cmVNYW5hZ2VyQ2xhc3MoKTtcbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7OzthQVVzQztpQkFDWTtXQUVHO3FCQUNLO3FCQUdGO1lBUWpDO2lC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
|
|
650
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZml4dHVyZS1tYW5hZ2VyLmpzIiwibmFtZXMiOltdLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy90ZXN0aW5nL2ZpeHR1cmUtbWFuYWdlci50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgYXNzZXJ0IGZyb20gXCJhc3NlcnRcIjtcbmltcG9ydCB7IGV4ZWNTeW5jLCB0eXBlIEV4ZWNTeW5jT3B0aW9ucyB9IGZyb20gXCJjaGlsZF9wcm9jZXNzXCI7XG5pbXBvcnQgeyByZWFkRmlsZVN5bmMsIHdyaXRlRmlsZVN5bmMgfSBmcm9tIFwiZnNcIjtcbmltcG9ydCB7IGluc3BlY3QgfSBmcm9tIFwidXRpbFwiO1xuXG5pbXBvcnQgY2hhbGsgZnJvbSBcImNoYWxrXCI7XG5pbXBvcnQgaW5mbGVjdGlvbiBmcm9tIFwiaW5mbGVjdGlvblwiO1xuaW1wb3J0IHsgdHlwZSBLbmV4IH0gZnJvbSBcImtuZXhcIjtcbmltcG9ydCB7IHVuaXF1ZSB9IGZyb20gXCJyYWRhc2hpXCI7XG5pbXBvcnQgeyB6IH0gZnJvbSBcInpvZFwiO1xuXG5pbXBvcnQgeyBTb25hbXUgfSBmcm9tIFwiLi4vYXBpL3NvbmFtdVwiO1xuaW1wb3J0IHsgQmFzZU1vZGVsIH0gZnJvbSBcIi4uL2RhdGFiYXNlL2Jhc2UtbW9kZWxcIjtcbmltcG9ydCB7IHR5cGUgU29uYW11REJDb25maWcgfSBmcm9tIFwiLi4vZGF0YWJhc2UvZGJcIjtcbmltcG9ydCB7IGNyZWF0ZUtuZXhJbnN0YW5jZSB9IGZyb20gXCIuLi9kYXRhYmFzZS9rbmV4XCI7XG5pbXBvcnQgeyBVcHNlcnRCdWlsZGVyIH0gZnJvbSBcIi4uL2RhdGFiYXNlL3Vwc2VydC1idWlsZGVyXCI7XG5pbXBvcnQgeyB0eXBlIFVCUmVmIH0gZnJvbSBcIi4uL2RhdGFiYXNlL3Vwc2VydC1idWlsZGVyXCI7XG5pbXBvcnQgeyB0eXBlIEVudGl0eSB9IGZyb20gXCIuLi9lbnRpdHkvZW50aXR5XCI7XG5pbXBvcnQgeyBFbnRpdHlNYW5hZ2VyIH0gZnJvbSBcIi4uL2VudGl0eS9lbnRpdHktbWFuYWdlclwiO1xuaW1wb3J0IHtcbiAgaXNCZWxvbmdzVG9PbmVSZWxhdGlvblByb3AsXG4gIGlzSGFzTWFueVJlbGF0aW9uUHJvcCxcbiAgaXNNYW55VG9NYW55UmVsYXRpb25Qcm9wLFxuICBpc09uZVRvT25lUmVsYXRpb25Qcm9wLFxuICBpc1JlbGF0aW9uUHJvcCxcbiAgaXNWaXJ0dWFsUHJvcCxcbn0gZnJvbSBcIi4uL3R5cGVzL3R5cGVzXCI7XG5pbXBvcnQge1xuICB0eXBlIEJlbG9uZ3NUb09uZVJlbGF0aW9uUHJvcCxcbiAgdHlwZSBEYXRhYmFzZVNjaGVtYUV4dGVuZCxcbiAgdHlwZSBFbnRpdHlQcm9wLFxuICB0eXBlIEZpeHR1cmVJbXBvcnRSZXN1bHQsXG4gIHR5cGUgRml4dHVyZVJlY29yZCxcbiAgdHlwZSBGaXh0dXJlU2VhcmNoT3B0aW9ucyxcbiAgdHlwZSBPbmVUb09uZVJlbGF0aW9uUHJvcCxcbn0gZnJvbSBcIi4uL3R5cGVzL3R5cGVzXCI7XG5pbXBvcnQgeyBpc1Rlc3QgfSBmcm9tIFwiLi4vdXRpbHMvY29udHJvbGxlclwiO1xuaW1wb3J0IHsgUmVsYXRpb25HcmFwaCB9IGZyb20gXCIuL19yZWxhdGlvbi1ncmFwaFwiO1xuaW1wb3J0IHsgZGF0YUV4cGxvcmVyUmVjb3JkU2NoZW1hIH0gZnJvbSBcIi4vZGF0YS1leHBsb3JlclwiO1xuaW1wb3J0IHsgdHlwZSBEYXRhRXhwbG9yZXJSZWNvcmQsIHR5cGUgRGF0YUV4cGxvcmVyVmFsdWUgfSBmcm9tIFwiLi9kYXRhLWV4cGxvcmVyXCI7XG5cbmNvbnN0IHBnQ29ubmVjdGlvblNjaGVtYSA9IHpcbiAgLm9iamVjdCh7XG4gICAgaG9zdDogei5zdHJpbmcoKS5vcHRpb25hbCgpLFxuICAgIHBvcnQ6IHoubnVtYmVyKCkub3B0aW9uYWwoKSxcbiAgICB1c2VyOiB6LnN0cmluZygpLm9wdGlvbmFsKCksXG4gICAgcGFzc3dvcmQ6IHouc3RyaW5nKCkub3B0aW9uYWwoKSxcbiAgICBkYXRhYmFzZTogei5zdHJpbmcoKSxcbiAgfSlcbiAgLnBhc3N0aHJvdWdoKCk7XG5jb25zdCBkYXRhYmFzZUNvbm5lY3Rpb25TY2hlbWEgPSB6Lm9iamVjdCh7IGRhdGFiYXNlOiB6LnN0cmluZygpIH0pLnBhc3N0aHJvdWdoKCk7XG5jb25zdCBmaXh0dXJlUmVjb3JkSWRzU2NoZW1hID0gei5hcnJheSh6LnVuaW9uKFt6Lm51bWJlcigpLCB6LnN0cmluZygpXSkpO1xuY29uc3QgcmVsYXRpb25JZFNjaGVtYSA9IHoudW5pb24oW3oubnVtYmVyKCksIHouc3RyaW5nKCksIHoubnVsbCgpXSk7XG5cbmV4cG9ydCB0eXBlIEZpeHR1cmVTb3VyY2VSZWNvcmQgPSBEYXRhRXhwbG9yZXJSZWNvcmQgJiB7XG4gIGlkOiBudW1iZXIgfCBzdHJpbmc7XG59O1xuXG50eXBlIFVwc2VydFJvd1ZhbHVlID0gRGF0YUV4cGxvcmVyVmFsdWUgfCBVQlJlZjtcbnR5cGUgVXBzZXJ0Um93ID0ge1xuICBbY29sdW1uTmFtZTogc3RyaW5nXTogVXBzZXJ0Um93VmFsdWU7XG59O1xuXG5mdW5jdGlvbiBleGVjdXRlRml4dHVyZVN5bmNDb21tYW5kKGNvbW1hbmQ6IHN0cmluZywgb3B0aW9uczogRXhlY1N5bmNPcHRpb25zKTogdm9pZCB7XG4gIHRyeSB7XG4gICAgZXhlY1N5bmMoY29tbWFuZCwgb3B0aW9ucyk7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiRml4dHVyZSBkYXRhYmFzZSBzeW5jaHJvbml6YXRpb24gY29tbWFuZCBmYWlsZWRcIiwgeyBjYXVzZTogZXJyb3IgfSk7XG4gIH1cbn1cblxuLyoqIOyCrOyaqeyekCDsp4DsoJUg7KSR67O1IO2ZleyduCDsu6zrn7wgKGVudGl0eUlk67OE66GcIOyngOyglSkgKi9cbmV4cG9ydCBpbnRlcmZhY2UgRHVwbGljYXRlQ2hlY2tPcHRpb25zIHtcbiAgY29sdW1ucz86IHtcbiAgICBbZW50aXR5SWQ6IHN0cmluZ106IHN0cmluZ1tdO1xuICB9O1xufVxuXG5leHBvcnQgY2xhc3MgRml4dHVyZU1hbmFnZXJDbGFzcyB7XG4gIHByaXZhdGUgdGVzdGluZ0RiOiBLbmV4IHwgbnVsbCA9IG51bGw7XG4gIHNldCB0ZGIodGRiOiBLbmV4KSB7XG4gICAgdGhpcy50ZXN0aW5nRGIgPSB0ZGI7XG4gIH1cbiAgZ2V0IHRkYigpOiBLbmV4IHtcbiAgICBpZiAodGhpcy50ZXN0aW5nRGIgPT09IG51bGwpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkZpeHR1cmVNYW5hZ2VyIGhhcyBub3QgYmVlbiBpbml0aWFsaXplZFwiKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMudGVzdGluZ0RiO1xuICB9XG5cbiAgcHJpdmF0ZSBmaXh0dXJlRGI6IEtuZXggfCBudWxsID0gbnVsbDtcbiAgc2V0IGZkYihmZGI6IEtuZXgpIHtcbiAgICB0aGlzLmZpeHR1cmVEYiA9IGZkYjtcbiAgfVxuICBnZXQgZmRiKCk6IEtuZXgge1xuICAgIGlmICh0aGlzLmZpeHR1cmVEYiA9PT0gbnVsbCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiRml4dHVyZU1hbmFnZXIgaGFzIG5vdCBiZWVuIGluaXRpYWxpemVkXCIpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5maXh0dXJlRGI7XG4gIH1cbiAgY2FjaGVkVGFibGVOYW1lczogc3RyaW5nW10gfCBudWxsID0gbnVsbDtcblxuICBwcml2YXRlIHJlbGF0aW9uR3JhcGggPSBuZXcgUmVsYXRpb25HcmFwaCgpO1xuXG4gIC8vIFVwc2VydEJ1aWxkZXIg6riw67CYIGltcG9ydOulvCDsnITtlZwg7IOB7YOcXG4gIHByaXZhdGUgYnVpbGRlcjogVXBzZXJ0QnVpbGRlciA9IG5ldyBVcHNlcnRCdWlsZGVyKCk7XG4gIHByaXZhdGUgZml4dHVyZVJlZk1hcDogTWFwPHN0cmluZywgVUJSZWY+ID0gbmV3IE1hcCgpO1xuICBwcml2YXRlIHNraXBwZWRGaXh0dXJlczogTWFwPHN0cmluZywgeyBlbnRpdHlJZDogc3RyaW5nOyBleGlzdGluZ0lkOiBudW1iZXIgfCBzdHJpbmcgfT4gPVxuICAgIG5ldyBNYXAoKTtcblxuICBpbml0KCkge1xuICAgIGlmICh0aGlzLnRlc3RpbmdEYiAhPT0gbnVsbCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoU29uYW11LmRiQ29uZmlnLnRlc3QgJiYgU29uYW11LmRiQ29uZmlnLnByb2R1Y3Rpb24pIHtcbiAgICAgIGNvbnN0IHRDb25uID0gcGdDb25uZWN0aW9uU2NoZW1hLnBhcnNlKFNvbmFtdS5kYkNvbmZpZy50ZXN0LmNvbm5lY3Rpb24pO1xuICAgICAgY29uc3QgcENvbm4gPSBwZ0Nvbm5lY3Rpb25TY2hlbWEucGFyc2UoU29uYW11LmRiQ29uZmlnLnByb2R1Y3Rpb24uY29ubmVjdGlvbik7XG4gICAgICBpZiAoXG4gICAgICAgIGAke3RDb25uLmhvc3QgPz8gXCJsb2NhbGhvc3RcIn06JHt0Q29ubi5wb3J0ID8/IDU0MzJ9LyR7dENvbm4uZGF0YWJhc2V9YCA9PT1cbiAgICAgICAgYCR7cENvbm4uaG9zdCA/PyBcImxvY2FsaG9zdFwifToke3BDb25uLnBvcnQgPz8gNTQzMn0vJHtwQ29ubi5kYXRhYmFzZX1gXG4gICAgICApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGDthYzsiqTtirhEQuyZgCDtlITroZzrjZXshZhEQuyXkCDrj5nsnbztlZwg642w7J207YSw67Kg7J207Iqk6rCAIOyCrOyaqeuQmOyXiOyKteuLiOuLpC5gKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLnRkYiA9IGNyZWF0ZUtuZXhJbnN0YW5jZShTb25hbXUuZGJDb25maWcudGVzdCk7XG4gICAgdGhpcy5mZGIgPSBjcmVhdGVLbmV4SW5zdGFuY2UoU29uYW11LmRiQ29uZmlnLmZpeHR1cmUpO1xuICB9XG5cbiAgLyoqXG4gICAg7JuQ6rKpIGZpeHR1cmUgRELrpbwg66Gc7LusIHRlc3QgRELroZwg67O17IKs7ZWp64uI64ukLlxuICAgIHBnX2R1bXDroZwg7JuQ6rKpIERC66W8IOuNpO2UhO2VmOqzoCwgcGdfcmVzdG9yZeuhnCDroZzsu6zsl5Ag67O17JuQ7ZWp64uI64ukLlxuICAqL1xuICBhc3luYyBzeW5jKCkge1xuICAgIGNvbnN0IGZpeHR1cmVDb25uID0gcGdDb25uZWN0aW9uU2NoZW1hLnBhcnNlKFNvbmFtdS5kYkNvbmZpZy5maXh0dXJlLmNvbm5lY3Rpb24pO1xuICAgIGNvbnN0IHRlc3RDb25uID0gcGdDb25uZWN0aW9uU2NoZW1hLnBhcnNlKFNvbmFtdS5kYkNvbmZpZy50ZXN0LmNvbm5lY3Rpb24pO1xuXG4gICAgLy8gMS4g66Gc7LusIHRlc3QgREIg7Jew6rKwIOyiheujjCDrsI8g7J6s7IOd7ISxXG4gICAgY29uc3QgdGVzdFBnRW52ID0geyBQR1BBU1NXT1JEOiB0ZXN0Q29ubi5wYXNzd29yZCB8fCBcIlwiIH07XG4gICAgZXhlY3V0ZUZpeHR1cmVTeW5jQ29tbWFuZChcbiAgICAgIGBwc3FsIC1oICR7dGVzdENvbm4uaG9zdH0gLXAgJHt0ZXN0Q29ubi5wb3J0ID8/IDU0MzJ9IC1VICR7dGVzdENvbm4udXNlcn0gLWQgcG9zdGdyZXMgLWMgXCJcbiAgICAgICAgU0VMRUNUIHBnX3Rlcm1pbmF0ZV9iYWNrZW5kKHBnX3N0YXRfYWN0aXZpdHkucGlkKVxuICAgICAgICBGUk9NIHBnX3N0YXRfYWN0aXZpdHlcbiAgICAgICAgV0hFUkUgZGF0bmFtZSA9ICcke3Rlc3RDb25uLmRhdGFiYXNlfSdcbiAgICAgICAgICBBTkQgcGlkIDw+IHBnX2JhY2tlbmRfcGlkKCk7XG4gICAgICBcImAsXG4gICAgICB7IHN0ZGlvOiBcImluaGVyaXRcIiwgZW52OiB7IC4uLnByb2Nlc3MuZW52LCAuLi50ZXN0UGdFbnYgfSB9LFxuICAgICk7XG5cbiAgICBleGVjdXRlRml4dHVyZVN5bmNDb21tYW5kKFxuICAgICAgYHBzcWwgLWggJHt0ZXN0Q29ubi5ob3N0fSAtcCAke3Rlc3RDb25uLnBvcnQgPz8gNTQzMn0gLVUgJHt0ZXN0Q29ubi51c2VyfSAtZCBwb3N0Z3JlcyAtYyBcIkRST1AgREFUQUJBU0UgSUYgRVhJU1RTIFxcXFxcIiR7dGVzdENvbm4uZGF0YWJhc2V9XFxcXFwiXCJgLFxuICAgICAgeyBzdGRpbzogXCJpbmhlcml0XCIsIGVudjogeyAuLi5wcm9jZXNzLmVudiwgLi4udGVzdFBnRW52IH0gfSxcbiAgICApO1xuXG4gICAgZXhlY3V0ZUZpeHR1cmVTeW5jQ29tbWFuZChcbiAgICAgIGBwc3FsIC1oICR7dGVzdENvbm4uaG9zdH0gLXAgJHt0ZXN0Q29ubi5wb3J0ID8/IDU0MzJ9IC1VICR7dGVzdENvbm4udXNlcn0gLWQgcG9zdGdyZXMgLWMgXCJDUkVBVEUgREFUQUJBU0UgXFxcXFwiJHt0ZXN0Q29ubi5kYXRhYmFzZX1cXFxcXCJcImAsXG4gICAgICB7IHN0ZGlvOiBcImluaGVyaXRcIiwgZW52OiB7IC4uLnByb2Nlc3MuZW52LCAuLi50ZXN0UGdFbnYgfSB9LFxuICAgICk7XG5cbiAgICAvLyAyLiDsm5DqsqkgZml4dHVyZSBEQiDihpIg66Gc7LusIHRlc3QgRELroZwg67O17IKsIChwZ19kdW1wIHwgcGdfcmVzdG9yZSlcbiAgICBjb25zdCBmaXh0dXJlUGdFbnYgPSB7IFBHUEFTU1dPUkQ6IGZpeHR1cmVDb25uLnBhc3N3b3JkIHx8IFwiXCIgfTtcbiAgICBjb25zdCBkdW1wQ21kID0gYHBnX2R1bXAgLWggJHtmaXh0dXJlQ29ubi5ob3N0fSAtcCAke2ZpeHR1cmVDb25uLnBvcnQgPz8gNTQzMn0gLVUgJHtmaXh0dXJlQ29ubi51c2VyfSAtZCAke2ZpeHR1cmVDb25uLmRhdGFiYXNlfSAtRmNgO1xuICAgIGNvbnN0IHJlc3RvcmVDbWQgPSBgcGdfcmVzdG9yZSAtaCAke3Rlc3RDb25uLmhvc3R9IC1wICR7dGVzdENvbm4ucG9ydCA/PyA1NDMyfSAtVSAke3Rlc3RDb25uLnVzZXJ9IC1kICR7dGVzdENvbm4uZGF0YWJhc2V9IC0tbm8tb3duZXIgLS1uby1hY2xgO1xuXG4gICAgZXhlY3V0ZUZpeHR1cmVTeW5jQ29tbWFuZChcbiAgICAgIGAke2R1bXBDbWR9IHwgUEdQQVNTV09SRD1cIiR7dGVzdENvbm4ucGFzc3dvcmQgfHwgXCJcIn1cIiAke3Jlc3RvcmVDbWR9YCxcbiAgICAgIHtcbiAgICAgICAgc3RkaW86IFwiaW5oZXJpdFwiLFxuICAgICAgICBlbnY6IHsgLi4ucHJvY2Vzcy5lbnYsIC4uLmZpeHR1cmVQZ0VudiB9LFxuICAgICAgICBzaGVsbDogXCIvYmluL2Jhc2hcIixcbiAgICAgIH0sXG4gICAgKTtcblxuICAgIC8vIDMuIOyLnO2AgOyKpCDrpqzshYsgKOuNsOydtO2EsCDrs7Xsgqwg7ZuEIOyLnO2AgOyKpOulvCBNQVgoaWQp66GcIOygleugrClcbiAgICBhd2FpdCB0aGlzLnJlc2V0U2VxdWVuY2VzKFNvbmFtdS5kYkNvbmZpZy50ZXN0KTtcbiAgfVxuXG4gIC8qKlxuICAgKiDrqqjrk6Ag7YWM7J2067iU7J2YIOyLnO2AgOyKpOulvCDtmITsnqwgTUFYKGlkKeuhnCDrpqzshYvtlanri4jri6QuXG4gICAqIGZpeHR1cmUgc3luYyDtm4Qg7Iuc7YCA7Iqk6rCAIOyLpOygnCDrjbDsnbTthLDsmYAg66ee7KeAIOyViuuKlCDrrLjsoJzrpbwg7ZW06rKw7ZWp64uI64ukLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyByZXNldFNlcXVlbmNlcyhkYkNvbmZpZzogU29uYW11REJDb25maWdbXCJ0ZXN0XCJdKSB7XG4gICAgY29uc3QgdGVzdERiID0gY3JlYXRlS25leEluc3RhbmNlKGRiQ29uZmlnKTtcbiAgICBjb25zdCBlbnRpdGllcyA9IEVudGl0eU1hbmFnZXIuZ2V0QWxsRW50aXRpZXMoKTtcblxuICAgIHRyeSB7XG4gICAgICBmb3IgKGNvbnN0IGVudGl0eSBvZiBlbnRpdGllcykge1xuICAgICAgICBjb25zdCB0YWJsZU5hbWUgPSBlbnRpdHkudGFibGUgfHwgZW50aXR5LmlkLnRvTG93ZXJDYXNlKCk7XG5cbiAgICAgICAgLy8gaWQg7ZWE65Oc7J2YIO2DgOyeheydhCDtmZXsnbjtlanri4jri6RcbiAgICAgICAgY29uc3QgaWRQcm9wID0gZW50aXR5LnByb3BzLmZpbmQoKHApID0+IHAubmFtZSA9PT0gXCJpZFwiKTtcbiAgICAgICAgY29uc3QgaWRUeXBlID0gaWRQcm9wPy50eXBlO1xuXG4gICAgICAgIC8vIGludGVnZXIvYmlnSW50ZWdlcuydtOqxsOuCmCwgc3RyaW5n7J207KeA66eMIGZpeHR1cmVTdHJhdGVneT1zZXF1ZW5jZeyduCDqsr3smrDsl5Drp4wg66as7IWL7ZWp64uI64ukXG4gICAgICAgIGNvbnN0IHVzZXNTZXF1ZW5jZSA9XG4gICAgICAgICAgaWRUeXBlID09PSBcImludGVnZXJcIiB8fFxuICAgICAgICAgIGlkVHlwZSA9PT0gXCJiaWdJbnRlZ2VyXCIgfHxcbiAgICAgICAgICBpZFByb3A/LmNvbmU/LmZpeHR1cmVTdHJhdGVneSA9PT0gXCJzZXF1ZW5jZVwiO1xuXG4gICAgICAgIGlmICghdXNlc1NlcXVlbmNlKSB7XG4gICAgICAgICAgIWlzVGVzdCgpICYmXG4gICAgICAgICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgICAgICAgYFNraXBwaW5nIHNlcXVlbmNlIHJlc2V0IGZvciAke3RhYmxlTmFtZX0gKGlkIHR5cGU6ICR7aWRUeXBlIHx8IFwidW5rbm93blwifSlgLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFBvc3RncmVTUUwg7Iuc7YCA7Iqk66W8IO2YhOyerCDthYzsnbTruJTsnZggTUFYKGlkKeuhnCDrpqzshYvtlanri4jri6QuXG4gICAgICAgIC8vIHN0cmluZyDtg4DsnoXsnZgg6rK97JqwIOyIq+yekCDsupDsiqTtjIXsnbQg7ZWE7JqU7ZWp64uI64ukLlxuICAgICAgICBjb25zdCBtYXhFeHByID0gaWRUeXBlID09PSBcInN0cmluZ1wiID8gXCJNQVgoaWQ6OmJpZ2ludClcIiA6IFwiTUFYKGlkKVwiO1xuICAgICAgICBhd2FpdCB0ZXN0RGIucmF3KGBcbiAgICAgICAgICBTRUxFQ1Qgc2V0dmFsKFxuICAgICAgICAgICAgcGdfZ2V0X3NlcmlhbF9zZXF1ZW5jZSgncHVibGljLiR7dGFibGVOYW1lfScsICdpZCcpLFxuICAgICAgICAgICAgQ09BTEVTQ0UoKFNFTEVDVCAke21heEV4cHJ9IEZST00gJHt0YWJsZU5hbWV9KSwgMSlcbiAgICAgICAgICApXG4gICAgICAgIGApO1xuICAgICAgfVxuICAgIH0gZmluYWxseSB7XG4gICAgICBhd2FpdCB0ZXN0RGIuZGVzdHJveSgpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgdmlzaXRlZFJlY29yZHMgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgYXN5bmMgaW1wb3J0Rml4dHVyZShlbnRpdHlJZDogc3RyaW5nLCBpZHM6IG51bWJlcltdKSB7XG4gICAgLy8g67Cp66y4IOq4sOuhnSDstIjquLDtmZQgKOyDiOuhnOyatCBpbXBvcnQg7J6R7JeFIOyLnOyekSlcbiAgICB0aGlzLnZpc2l0ZWRSZWNvcmRzLmNsZWFyKCk7XG5cbiAgICBjb25zdCBxdWVyaWVzID0gdW5pcXVlKFxuICAgICAgKFxuICAgICAgICBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgICAgICBpZHMubWFwKGFzeW5jIChpZCkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuZ2V0SW1wb3J0UXVlcmllcyhlbnRpdHlJZCwgXCJpZFwiLCBpZCk7XG4gICAgICAgICAgfSksXG4gICAgICAgIClcbiAgICAgICkuZmxhdCgpLFxuICAgICk7XG5cbiAgICBjb25zdCB3ZGIgPSBCYXNlTW9kZWwuZ2V0REIoXCJ3XCIpO1xuICAgIGZvciAoY29uc3QgcXVlcnkgb2YgcXVlcmllcykge1xuICAgICAgYXdhaXQgd2RiLnJhdyhxdWVyeSk7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgZ2V0SW1wb3J0UXVlcmllcyhlbnRpdHlJZDogc3RyaW5nLCBmaWVsZDogc3RyaW5nLCBpZDogbnVtYmVyKTogUHJvbWlzZTxzdHJpbmdbXT4ge1xuICAgIGNvbnN0IHJlY29yZEtleSA9IGAke2VudGl0eUlkfSMke2ZpZWxkfSMke2lkfWA7XG5cbiAgICAvLyDsiJztmZgg7LC47KGwIOuwqeyngDog7J2066+4IOuwqeusuO2VnCDroIjsvZTrk5zripQg7Iqk7YK1XG4gICAgaWYgKHRoaXMudmlzaXRlZFJlY29yZHMuaGFzKHJlY29yZEtleSkpIHtcbiAgICAgIHJldHVybiBbXTtcbiAgICB9XG4gICAgdGhpcy52aXNpdGVkUmVjb3Jkcy5hZGQocmVjb3JkS2V5KTtcblxuICAgIGNvbnN0IGVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0KGVudGl0eUlkKTtcbiAgICBjb25zdCB3ZGIgPSBCYXNlTW9kZWwuZ2V0REIoXCJ3XCIpO1xuXG4gICAgLy8g7Jes6riw7IScIOyLpERC7J2YIHJvdyDqsIDsoLjsmLRcbiAgICBjb25zdCBbcm93XSA9IGF3YWl0IHdkYihlbnRpdHkudGFibGUpLndoZXJlKGZpZWxkLCBpZCkubGltaXQoMSk7XG4gICAgaWYgKHJvdyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7ZW50aXR5SWR9IyR7aWR9IHJvd+ulvCDssL7snYQg7IiYIOyXhuyKteuLiOuLpC5gKTtcbiAgICB9XG5cbiAgICAvLyDtlL3siqTss5BEQiwg7IukREJcbiAgICBjb25zdCBmaXh0dXJlRGF0YWJhc2UgPSBkYXRhYmFzZUNvbm5lY3Rpb25TY2hlbWEucGFyc2UoXG4gICAgICBTb25hbXUuZGJDb25maWcuZml4dHVyZS5jb25uZWN0aW9uLFxuICAgICkuZGF0YWJhc2U7XG4gICAgY29uc3QgcmVhbERhdGFiYXNlID0gZGF0YWJhc2VDb25uZWN0aW9uU2NoZW1hLnBhcnNlKFxuICAgICAgU29uYW11LmRiQ29uZmlnLnByb2R1Y3Rpb24uY29ubmVjdGlvbixcbiAgICApLmRhdGFiYXNlO1xuXG4gICAgY29uc3Qgc2VsZlF1ZXJ5ID0gYElOU0VSVCBJR05PUkUgSU5UTyBcXGAke2ZpeHR1cmVEYXRhYmFzZX1cXGAuXFxgJHtlbnRpdHkudGFibGV9XFxgIChTRUxFQ1QgKiBGUk9NIFxcYCR7cmVhbERhdGFiYXNlfVxcYC5cXGAke2VudGl0eS50YWJsZX1cXGAgV0hFUkUgXFxgaWRcXGAgPSAke2lkfSlgO1xuXG4gICAgY29uc3QgYXJncyA9IE9iamVjdC5lbnRyaWVzKGVudGl0eS5yZWxhdGlvbnMpXG4gICAgICAuZmlsdGVyKFxuICAgICAgICAoWywgcmVsYXRpb25dKSA9PlxuICAgICAgICAgIGlzQmVsb25nc1RvT25lUmVsYXRpb25Qcm9wKHJlbGF0aW9uKSB8fFxuICAgICAgICAgIChpc09uZVRvT25lUmVsYXRpb25Qcm9wKHJlbGF0aW9uKSAmJiByZWxhdGlvbi5jdXN0b21Kb2luQ2xhdXNlID09PSB1bmRlZmluZWQpLFxuICAgICAgKVxuICAgICAgLm1hcCgoWywgcmVsYXRpb25dKSA9PiB7XG4gICAgICAgIC8qXG4gICAgICAgIEJlbG9uZ3NUb09uZeyduCDqsr3smrBcbiAgICAgICAgICBDYXRlZ29yeSAvICdpZCcgLyByb3dbY2F0ZWdvcnlfaWRdIO2YuOy2nFxuICAgICAgICBPbmVUb09uZeyXkCBqb2luQ29sdW1uID09PSB0cnVlIOyduCDqsr3smrBcbiAgICAgICAgICBQcm9maWxlIC8gJ2lkJyAvIHJvd1twcm9maWxlX2lkXSDtmLjstpxcbiAgICAgICAgT25lVG9PbmXsl5Agam9pbkNvbHVtbiA9PT0gZmFsc2Ug7J24IOqyveyasFxuICAgICAgICAgIFByb2ZpbGUgLyAncHJvZmlsZV9pZCcgLyByb3dbJ2lkJ10g7Zi47LacXG4gICAgICAgICovXG4gICAgICAgIGxldCByZWxhdGlvbkZpZWxkOiBzdHJpbmc7XG4gICAgICAgIGxldCByZWxhdGlvbklkOiBudW1iZXI7XG4gICAgICAgIGlmIChpc09uZVRvT25lUmVsYXRpb25Qcm9wKHJlbGF0aW9uKSAmJiAhcmVsYXRpb24uaGFzSm9pbkNvbHVtbikge1xuICAgICAgICAgIGNvbnN0IHJlbGF0ZWRFbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChyZWxhdGlvbi53aXRoKTtcbiAgICAgICAgICBjb25zdCByZWxhdGVkSWRDb2x1bW5OYW1lID0gcmVsYXRlZEVudGl0eS5wcm9wcy5maW5kKFxuICAgICAgICAgICAgKHApID0+IGlzUmVsYXRpb25Qcm9wKHApICYmIHAud2l0aCA9PT0gZW50aXR5LmlkLFxuICAgICAgICAgICk/Lm5hbWU7XG4gICAgICAgICAgaWYgKCFyZWxhdGVkSWRDb2x1bW5OYW1lKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7cmVsYXRlZEVudGl0eS5pZH3snZggJHtlbnRpdHkuaWR9IOq0gOqzhCDtlITroa3snYQg7LC+7J2EIOyImCDsl4bsirXri4jri6QuYCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJlbGF0aW9uRmllbGQgPSBgJHtyZWxhdGVkSWRDb2x1bW5OYW1lfV9pZGA7XG4gICAgICAgICAgcmVsYXRpb25JZCA9IHJvdy5pZDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZWxhdGlvbkZpZWxkID0gXCJpZFwiO1xuICAgICAgICAgIHJlbGF0aW9uSWQgPSByb3dbYCR7cmVsYXRpb24ubmFtZX1faWRgXTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGVudGl0eUlkOiByZWxhdGlvbi53aXRoLFxuICAgICAgICAgIGZpZWxkOiByZWxhdGlvbkZpZWxkLFxuICAgICAgICAgIGlkOiByZWxhdGlvbklkLFxuICAgICAgICB9O1xuICAgICAgfSlcbiAgICAgIC5maWx0ZXIoKGFyZykgPT4gYXJnLmlkICE9PSBudWxsKTtcblxuICAgIGNvbnN0IHJlbFF1ZXJpZXMgPSBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgIGFyZ3MubWFwKGFzeW5jIChyZWxhdGlvbkFyZ3MpID0+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0SW1wb3J0UXVlcmllcyhyZWxhdGlvbkFyZ3MuZW50aXR5SWQsIHJlbGF0aW9uQXJncy5maWVsZCwgcmVsYXRpb25BcmdzLmlkKTtcbiAgICAgIH0pLFxuICAgICk7XG5cbiAgICByZXR1cm4gWy4uLnVuaXF1ZShyZWxRdWVyaWVzLnRvUmV2ZXJzZWQoKS5mbGF0KCkpLCBzZWxmUXVlcnldO1xuICB9XG5cbiAgYXN5bmMgZGVzdHJveSgpIHtcbiAgICBpZiAodGhpcy50ZXN0aW5nRGIpIHtcbiAgICAgIGF3YWl0IHRoaXMudGVzdGluZ0RiLmRlc3Ryb3koKTtcbiAgICAgIHRoaXMudGVzdGluZ0RiID0gbnVsbDtcbiAgICB9XG4gICAgaWYgKHRoaXMuZml4dHVyZURiKSB7XG4gICAgICBhd2FpdCB0aGlzLmZpeHR1cmVEYi5kZXN0cm95KCk7XG4gICAgICB0aGlzLmZpeHR1cmVEYiA9IG51bGw7XG4gICAgfVxuICAgIGF3YWl0IEJhc2VNb2RlbC5kZXN0cm95KCk7XG4gIH1cblxuICBhc3luYyBnZXRGaXh0dXJlcyhcbiAgICBzb3VyY2VEQk5hbWU6IGtleW9mIFNvbmFtdURCQ29uZmlnLFxuICAgIHRhcmdldERCTmFtZToga2V5b2YgU29uYW11REJDb25maWcsXG4gICAgc2VhcmNoT3B0aW9uczogRml4dHVyZVNlYXJjaE9wdGlvbnMsXG4gICAgZHVwbGljYXRlQ2hlY2s/OiBEdXBsaWNhdGVDaGVja09wdGlvbnMsXG4gICkge1xuICAgIGNvbnN0IHNvdXJjZURCID0gY3JlYXRlS25leEluc3RhbmNlKFNvbmFtdS5kYkNvbmZpZ1tzb3VyY2VEQk5hbWVdKTtcbiAgICBjb25zdCB0YXJnZXREQiA9IGNyZWF0ZUtuZXhJbnN0YW5jZShTb25hbXUuZGJDb25maWdbdGFyZ2V0REJOYW1lXSk7XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgeyBlbnRpdHlJZCwgZmllbGQsIHZhbHVlLCBzZWFyY2hUeXBlIH0gPSBzZWFyY2hPcHRpb25zO1xuXG4gICAgICBjb25zdCBlbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChlbnRpdHlJZCk7XG4gICAgICBjb25zdCBjb2x1bW4gPVxuICAgICAgICBlbnRpdHkucHJvcHMuZmluZCgocHJvcCkgPT4gcHJvcC5uYW1lID09PSBmaWVsZCk/LnR5cGUgPT09IFwicmVsYXRpb25cIlxuICAgICAgICAgID8gYCR7ZmllbGR9X2lkYFxuICAgICAgICAgIDogZmllbGQ7XG5cbiAgICAgIGxldCBxdWVyeSA9IHNvdXJjZURCKGVudGl0eS50YWJsZSk7XG4gICAgICBpZiAoc2VhcmNoVHlwZSA9PT0gXCJlcXVhbHNcIikge1xuICAgICAgICBxdWVyeSA9IHF1ZXJ5LndoZXJlKGNvbHVtbiwgdmFsdWUpO1xuICAgICAgfSBlbHNlIGlmIChzZWFyY2hUeXBlID09PSBcImxpa2VcIikge1xuICAgICAgICBxdWVyeSA9IHF1ZXJ5LndoZXJlKGNvbHVtbiwgXCJsaWtlXCIsIGAlJHt2YWx1ZX0lYCk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHJvd3MgPSBhd2FpdCBxdWVyeTtcbiAgICAgIGlmIChyb3dzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJObyByZWNvcmRzIGZvdW5kXCIpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBmaXh0dXJlczogRml4dHVyZVJlY29yZFtdID0gW107XG4gICAgICBmb3IgKGNvbnN0IHJvdyBvZiByb3dzKSB7XG4gICAgICAgIGNvbnN0IGluaXRpYWxSZWNvcmRzTGVuZ3RoID0gZml4dHVyZXMubGVuZ3RoO1xuICAgICAgICBjb25zdCBuZXdSZWNvcmRzID0gYXdhaXQgdGhpcy5jcmVhdGVGaXh0dXJlUmVjb3JkKGVudGl0eSwgcm93LCB7XG4gICAgICAgICAgZGI6IHNvdXJjZURCLFxuICAgICAgICB9KTtcbiAgICAgICAgZml4dHVyZXMucHVzaCguLi5uZXdSZWNvcmRzKTtcbiAgICAgICAgY29uc3QgY3VycmVudEZpeHR1cmVSZWNvcmQgPSBmaXh0dXJlcy5maW5kKChyKSA9PiByLmZpeHR1cmVJZCA9PT0gYCR7ZW50aXR5SWR9IyR7cm93LmlkfWApO1xuXG4gICAgICAgIGlmIChjdXJyZW50Rml4dHVyZVJlY29yZCkge1xuICAgICAgICAgIC8vIO2YhOyerCBmaXh0dXJl66Gc67aA7YSwIOyDneyEseuQnCBmZXRjaGVkUmVjb3JkcyDshKTsoJVcbiAgICAgICAgICBjdXJyZW50Rml4dHVyZVJlY29yZC5mZXRjaGVkUmVjb3JkcyA9IGZpeHR1cmVzXG4gICAgICAgICAgICAuZmlsdGVyKChyKSA9PiByLmZpeHR1cmVJZCAhPT0gY3VycmVudEZpeHR1cmVSZWNvcmQuZml4dHVyZUlkKVxuICAgICAgICAgICAgLnNsaWNlKGluaXRpYWxSZWNvcmRzTGVuZ3RoKVxuICAgICAgICAgICAgLm1hcCgocikgPT4gci5maXh0dXJlSWQpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGZvciAoY29uc3QgZml4dHVyZSBvZiBmaXh0dXJlcykge1xuICAgICAgICBjb25zdCBmaXh0dXJlRW50aXR5ID0gRW50aXR5TWFuYWdlci5nZXQoZml4dHVyZS5lbnRpdHlJZCk7XG5cbiAgICAgICAgLy8g7IKs7Jqp7J6QIOyngOyglSDsu6zrn7wg6riw7KSAIOykkeuztSDtmZXsnbgg4oaSIHRhcmdldFxuICAgICAgICBjb25zdCBjdXN0b21Db2x1bW5zID0gZHVwbGljYXRlQ2hlY2s/LmNvbHVtbnM/LltmaXh0dXJlLmVudGl0eUlkXTtcbiAgICAgICAgaWYgKGN1c3RvbUNvbHVtbnMgJiYgY3VzdG9tQ29sdW1ucy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgY29uc3QgY3VzdG9tRHVwbGljYXRlUm93ID0gYXdhaXQgdGhpcy5jaGVja0R1cGxpY2F0ZUJ5Q29sdW1ucyhcbiAgICAgICAgICAgIHRhcmdldERCLFxuICAgICAgICAgICAgZml4dHVyZUVudGl0eSxcbiAgICAgICAgICAgIGZpeHR1cmUsXG4gICAgICAgICAgICBjdXN0b21Db2x1bW5zLFxuICAgICAgICAgICk7XG4gICAgICAgICAgaWYgKGN1c3RvbUR1cGxpY2F0ZVJvdykge1xuICAgICAgICAgICAgY29uc3QgW3JlY29yZF0gPSBhd2FpdCB0aGlzLmNyZWF0ZUZpeHR1cmVSZWNvcmQoZml4dHVyZUVudGl0eSwgY3VzdG9tRHVwbGljYXRlUm93LCB7XG4gICAgICAgICAgICAgIHNpbmdsZVJlY29yZDogdHJ1ZSxcbiAgICAgICAgICAgICAgZGI6IHRhcmdldERCLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBmaXh0dXJlLnRhcmdldCA9IHJlY29yZDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBVbmlxdWUgaW5kZXgg6riw7KSAIOykkeuztSDtmZXsnbgg4oaSIGZpeHR1cmUudW5pcXVlXG4gICAgICAgIGNvbnN0IHVuaXF1ZVJvdyA9IGF3YWl0IHRoaXMuY2hlY2tVbmlxdWVWaW9sYXRpb24odGFyZ2V0REIsIGZpeHR1cmVFbnRpdHksIGZpeHR1cmUpO1xuICAgICAgICBpZiAodW5pcXVlUm93KSB7XG4gICAgICAgICAgY29uc3QgW3JlY29yZF0gPSBhd2FpdCB0aGlzLmNyZWF0ZUZpeHR1cmVSZWNvcmQoZml4dHVyZUVudGl0eSwgdW5pcXVlUm93LCB7XG4gICAgICAgICAgICBzaW5nbGVSZWNvcmQ6IHRydWUsXG4gICAgICAgICAgICBkYjogdGFyZ2V0REIsXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgZml4dHVyZS51bmlxdWUgPSByZWNvcmQ7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHVuaXF1ZShmaXh0dXJlcywgKGYpID0+IGYuZml4dHVyZUlkKTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgYXdhaXQgUHJvbWlzZS5hbGxTZXR0bGVkKFt0YXJnZXREQi5kZXN0cm95KCksIHNvdXJjZURCLmRlc3Ryb3koKV0pO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIGNyZWF0ZUZpeHR1cmVSZWNvcmQoXG4gICAgcm9vdEVudGl0eTogRW50aXR5LFxuICAgIHJvb3RSb3c6IEZpeHR1cmVTb3VyY2VSZWNvcmQsXG4gICAgb3B0aW9ucz86IHtcbiAgICAgIHNpbmdsZVJlY29yZD86IGJvb2xlYW47XG4gICAgICBkYj86IEtuZXg7XG4gICAgfSxcbiAgKTogUHJvbWlzZTxGaXh0dXJlUmVjb3JkW10+IHtcbiAgICBjb25zdCByZWNvcmRzOiBGaXh0dXJlUmVjb3JkW10gPSBbXTtcbiAgICBjb25zdCB2aXNpdGVkRW50aXRpZXMgPSBuZXcgU2V0PHN0cmluZz4oKTtcblxuICAgIGNvbnN0IGNyZWF0ZSA9IGFzeW5jIChlbnRpdHk6IEVudGl0eSwgcm93OiBGaXh0dXJlU291cmNlUmVjb3JkKSA9PiB7XG4gICAgICBjb25zdCBmaXh0dXJlSWQgPSBgJHtlbnRpdHkuaWR9IyR7cm93LmlkfWA7XG4gICAgICBpZiAodmlzaXRlZEVudGl0aWVzLmhhcyhmaXh0dXJlSWQpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHZpc2l0ZWRFbnRpdGllcy5hZGQoZml4dHVyZUlkKTtcblxuICAgICAgY29uc3QgcmVjb3JkOiBGaXh0dXJlUmVjb3JkID0ge1xuICAgICAgICBmaXh0dXJlSWQsXG4gICAgICAgIGVudGl0eUlkOiBlbnRpdHkuaWQsXG4gICAgICAgIGlkOiByb3cuaWQsXG4gICAgICAgIGNvbHVtbnM6IHt9LFxuICAgICAgICBmZXRjaGVkUmVjb3JkczogW10sXG4gICAgICAgIGJlbG9uZ3NSZWNvcmRzOiBbXSxcbiAgICAgIH07XG5cbiAgICAgIGZvciAoY29uc3QgcHJvcCBvZiBlbnRpdHkucHJvcHMpIHtcbiAgICAgICAgaWYgKGlzVmlydHVhbFByb3AocHJvcCkpIHtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFNBRkVUWTogRml4dHVyZVJlY29yZOydmCDroIjqsbDsi5wg6rCSIO2DgOyeheuztOuLpCDsi6TsoJwgREIvSlNPTiBmaXh0dXJlIOqwkiDqs4Tslb3snbQg64ST7Iq164uI64ukLlxuICAgICAgICBjb25zdCBjb2x1bW5WYWx1ZSA9IHJvd1twcm9wLm5hbWVdIGFzIEZpeHR1cmVSZWNvcmRbXCJjb2x1bW5zXCJdW3N0cmluZ11bXCJ2YWx1ZVwiXTtcbiAgICAgICAgcmVjb3JkLmNvbHVtbnNbcHJvcC5uYW1lXSA9IHtcbiAgICAgICAgICBwcm9wOiBwcm9wLFxuICAgICAgICAgIHZhbHVlOiBjb2x1bW5WYWx1ZSxcbiAgICAgICAgfTtcblxuICAgICAgICBjb25zdCBkYiA9IG9wdGlvbnM/LmRiID8/IEJhc2VNb2RlbC5nZXREQihcIndcIik7XG4gICAgICAgIGlmIChpc01hbnlUb01hbnlSZWxhdGlvblByb3AocHJvcCkpIHtcbiAgICAgICAgICBjb25zdCByZWxhdGVkRW50aXR5ID0gRW50aXR5TWFuYWdlci5nZXQocHJvcC53aXRoKTtcbiAgICAgICAgICBjb25zdCB0aHJvdWdoVGFibGUgPSBwcm9wLmpvaW5UYWJsZTtcbiAgICAgICAgICBjb25zdCBmcm9tQ29sdW1uID0gYCR7aW5mbGVjdGlvbi5zaW5ndWxhcml6ZShlbnRpdHkudGFibGUpfV9pZGA7XG4gICAgICAgICAgY29uc3QgdG9Db2x1bW4gPSBgJHtpbmZsZWN0aW9uLnNpbmd1bGFyaXplKHJlbGF0ZWRFbnRpdHkudGFibGUpfV9pZGA7XG5cbiAgICAgICAgICBjb25zdCByZWxhdGVkSWRzID0gYXdhaXQgZGIodGhyb3VnaFRhYmxlKS53aGVyZShmcm9tQ29sdW1uLCByb3cuaWQpLnBsdWNrKHRvQ29sdW1uKTtcbiAgICAgICAgICByZWNvcmQuY29sdW1uc1twcm9wLm5hbWVdLnZhbHVlID0gcmVsYXRlZElkcztcbiAgICAgICAgfSBlbHNlIGlmIChpc0hhc01hbnlSZWxhdGlvblByb3AocHJvcCkpIHtcbiAgICAgICAgICBjb25zdCByZWxhdGVkRW50aXR5ID0gRW50aXR5TWFuYWdlci5nZXQocHJvcC53aXRoKTtcbiAgICAgICAgICBjb25zdCByZWxhdGVkSWRzID0gYXdhaXQgZGIocmVsYXRlZEVudGl0eS50YWJsZSlcbiAgICAgICAgICAgIC53aGVyZShwcm9wLmpvaW5Db2x1bW4sIHJvdy5pZClcbiAgICAgICAgICAgIC5wbHVjayhcImlkXCIpO1xuICAgICAgICAgIHJlY29yZC5jb2x1bW5zW3Byb3AubmFtZV0udmFsdWUgPSByZWxhdGVkSWRzO1xuICAgICAgICB9IGVsc2UgaWYgKGlzT25lVG9PbmVSZWxhdGlvblByb3AocHJvcCkgJiYgIXByb3AuaGFzSm9pbkNvbHVtbikge1xuICAgICAgICAgIC8vIOyXreuwqe2WpSBPbmVUb09uZTogRkvrpbwg6rCA7KeEIOq0gOugqCDsl5Tti7Dti7Drpbwg7LC+7Iq164uI64ukXG4gICAgICAgICAgLy8g7JiI7IucOiBVc2VyIE9uZVRvT25lIEVtcGxveWVlIChFbXBsb3llZeqwgCB1c2VyX2lkIEZL66W8IOqwgOynkClcbiAgICAgICAgICBjb25zdCByZWxhdGVkRW50aXR5ID0gRW50aXR5TWFuYWdlci5nZXQocHJvcC53aXRoKTtcbiAgICAgICAgICBjb25zdCByZWxhdGVkUHJvcCA9IHJlbGF0ZWRFbnRpdHkucHJvcHMuZmluZChcbiAgICAgICAgICAgIChwKSA9PiBpc1JlbGF0aW9uUHJvcChwKSAmJiBwLndpdGggPT09IGVudGl0eS5pZCxcbiAgICAgICAgICApO1xuICAgICAgICAgIGlmIChyZWxhdGVkUHJvcCAmJiBpc1JlbGF0aW9uUHJvcChyZWxhdGVkUHJvcCkpIHtcbiAgICAgICAgICAgIC8vIOq0gOugqCDsl5Tti7Dti7Dsl5DshJwgRksg7Lus65+87Jy866GcIOy/vOumrO2VqeuLiOuLpCAoaWTqsIAg7JWE64uYKVxuICAgICAgICAgICAgY29uc3QgZmtDb2x1bW4gPSBgJHtyZWxhdGVkUHJvcC5uYW1lfV9pZGA7XG4gICAgICAgICAgICBjb25zdCByZWxhdGVkUm93ID0gYXdhaXQgZGIocmVsYXRlZEVudGl0eS50YWJsZSkud2hlcmUoZmtDb2x1bW4sIHJvdy5pZCkuZmlyc3QoKTtcbiAgICAgICAgICAgIHJlY29yZC5jb2x1bW5zW3Byb3AubmFtZV0udmFsdWUgPSByZWxhdGVkUm93Py5pZDtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAoaXNSZWxhdGlvblByb3AocHJvcCkpIHtcbiAgICAgICAgICBjb25zdCByZWxhdGVkSWQgPSByZWxhdGlvbklkU2NoZW1hLnBhcnNlKHJvd1tgJHtwcm9wLm5hbWV9X2lkYF0pO1xuICAgICAgICAgIHJlY29yZC5jb2x1bW5zW3Byb3AubmFtZV0udmFsdWUgPSByZWxhdGVkSWQ7XG4gICAgICAgICAgaWYgKHJlbGF0ZWRJZCkge1xuICAgICAgICAgICAgcmVjb3JkLmJlbG9uZ3NSZWNvcmRzLnB1c2goYCR7cHJvcC53aXRofSMke3JlbGF0ZWRJZH1gKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKCFvcHRpb25zPy5zaW5nbGVSZWNvcmQgJiYgcmVsYXRlZElkKSB7XG4gICAgICAgICAgICBjb25zdCByZWxhdGVkRW50aXR5ID0gRW50aXR5TWFuYWdlci5nZXQocHJvcC53aXRoKTtcbiAgICAgICAgICAgIGNvbnN0IHJlbGF0ZWRSb3cgPSBhd2FpdCBkYihyZWxhdGVkRW50aXR5LnRhYmxlKS53aGVyZShcImlkXCIsIHJlbGF0ZWRJZCkuZmlyc3QoKTtcbiAgICAgICAgICAgIGlmIChyZWxhdGVkUm93KSB7XG4gICAgICAgICAgICAgIGF3YWl0IGNyZWF0ZShyZWxhdGVkRW50aXR5LCB7XG4gICAgICAgICAgICAgICAgLi4uZGF0YUV4cGxvcmVyUmVjb3JkU2NoZW1hLnBhcnNlKHJlbGF0ZWRSb3cpLFxuICAgICAgICAgICAgICAgIGlkOiB6LnVuaW9uKFt6Lm51bWJlcigpLCB6LnN0cmluZygpXSkucGFyc2UocmVsYXRlZFJvdy5pZCksXG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZWNvcmRzLnB1c2gocmVjb3JkKTtcbiAgICB9O1xuXG4gICAgYXdhaXQgY3JlYXRlKHJvb3RFbnRpdHksIHJvb3RSb3cpO1xuXG4gICAgcmV0dXJuIHJlY29yZHM7XG4gIH1cblxuICAvKipcbiAgICogMS4gUmVsYXRpb25HcmFwaOuhnCBmaXh0dXJlIOuLqOychCDsgr3snoUg7Iic7IScIOqzhOyCsCAoc2VsZi1yZWZlcmVuY2Ug7Y+s7ZWoKVxuICAgKiAyLiDthYzsnbTruJTrs4Qg66CI67Ko67OE66GcIFVwc2VydEJ1aWxkZXLsl5Ag65Ox66GdIOuwjyB1cHNlcnQg7Iuk7ZaJXG4gICAqIDMuIOyInOyEnCDquLDrsJggdXVpZOKGkmlkIOunpO2VkSAoVXBzZXJ0QnVpbGRlcuqwgCB1dWlk66W8IERC7JeQIOyggOyepe2VmOyngCDslYrsnLzrr4DroZwpXG4gICAqXG4gICAqIFVwc2VydEJ1aWxkZXLripQgc2VsZi1yZWZlcmVuY2XqsIAg7J6I7Jy866m0IGJ1aWxkSW5zZXJ0TGV2ZWxzKCnroZwg7J6s7KCV66Cs7ZWY7JesXG4gICAqIOuTseuhnSDsiJzshJzsmYAg67CY7ZmYIOyInOyEnOqwgCDri6zrnbzsp4gg7IiYIOyeiOyKteuLiOuLpC4g7J2066W8IOuwqeyngO2VmOq4sCDsnITtlbRcbiAgICogRml4dHVyZU1hbmFnZXLqsIAg66CI67Ko67OE66GcIOuCmOuIoOyEnCDsspjrpqztlZjsl6wg6rCBIHVwc2VydCDtmLjstpzsl5DshJzripRcbiAgICogc2VsZi1yZWZlcmVuY2XqsIAg7JeG64+E66GdIO2VqeuLiOuLpC5cbiAgICovXG4gIGFzeW5jIGluc2VydEZpeHR1cmVzKFxuICAgIGRiTmFtZToga2V5b2YgU29uYW11REJDb25maWcsXG4gICAgX2ZpeHR1cmVzOiBGaXh0dXJlUmVjb3JkW10sXG4gICk6IFByb21pc2U8Rml4dHVyZUltcG9ydFJlc3VsdFtdPiB7XG4gICAgY29uc3QgZml4dHVyZXMgPSB1bmlxdWUoX2ZpeHR1cmVzLCAoZikgPT4gZi5maXh0dXJlSWQpO1xuXG4gICAgLy8g7LSI6riw7ZmUXG4gICAgdGhpcy5idWlsZGVyID0gbmV3IFVwc2VydEJ1aWxkZXIoKTtcbiAgICB0aGlzLmZpeHR1cmVSZWZNYXAgPSBuZXcgTWFwKCk7XG4gICAgdGhpcy5za2lwcGVkRml4dHVyZXMgPSBuZXcgTWFwKCk7XG5cbiAgICAvLyDrs5HroKwg7YWM7Iqk7Yq4IOuqqOuTnOyXkOyEnOuKlCB3b3JrZXLrs4QgRELsl5Ag7KCA7J6lXG4gICAgY29uc3QgZGJDb25maWcgPVxuICAgICAgcHJvY2Vzcy5lbnYuU09OQU1VX1dPUktFUl9EQiA9PT0gXCJ0cnVlXCIgJiYgcHJvY2Vzcy5lbnYuVklURVNUX1BPT0xfSURcbiAgICAgICAgPyAoKCkgPT4ge1xuICAgICAgICAgICAgY29uc3Qgd29ya2VySWQgPSBwYXJzZUludChwcm9jZXNzLmVudi5WSVRFU1RfUE9PTF9JRCA/PyBcIjFcIiwgMTApO1xuICAgICAgICAgICAgY29uc3QgYmFzZUNvbmZpZyA9IFNvbmFtdS5kYkNvbmZpZ1tkYk5hbWVdO1xuICAgICAgICAgICAgY29uc3QgY29ubmVjdGlvbiA9IGRhdGFiYXNlQ29ubmVjdGlvblNjaGVtYS5wYXJzZShiYXNlQ29uZmlnLmNvbm5lY3Rpb24pO1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgLi4uYmFzZUNvbmZpZyxcbiAgICAgICAgICAgICAgY29ubmVjdGlvbjogeyAuLi5jb25uZWN0aW9uLCBkYXRhYmFzZTogYCR7Y29ubmVjdGlvbi5kYXRhYmFzZX1fJHt3b3JrZXJJZH1gIH0sXG4gICAgICAgICAgICAgIHBvb2w6IHsgbWluOiAxLCBtYXg6IDEgfSxcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfSkoKVxuICAgICAgICA6IFNvbmFtdS5kYkNvbmZpZ1tkYk5hbWVdO1xuICAgIGNvbnN0IGRiID0gY3JlYXRlS25leEluc3RhbmNlKGRiQ29uZmlnKTtcbiAgICBjb25zdCByZXN1bHRzOiBGaXh0dXJlSW1wb3J0UmVzdWx0W10gPSBbXTtcblxuICAgIHRyeSB7XG4gICAgICAvLyAxLiBSZWxhdGlvbkdyYXBo66GcIGZpeHR1cmUg64uo7JyEIOyCveyehSDsiJzshJwg6rOE7IKwXG4gICAgICB0aGlzLnJlbGF0aW9uR3JhcGguYnVpbGRHcmFwaChmaXh0dXJlcyk7XG4gICAgICBjb25zdCBpbnNlcnRpb25PcmRlciA9IHRoaXMucmVsYXRpb25HcmFwaC5nZXRJbnNlcnRpb25PcmRlcigpO1xuXG4gICAgICAvLyAyLiDsiqTtgrXtlaAgZml4dHVyZSDrqLzsoIAg7LKY66asIChvdmVycmlkZSDssrTtgawpXG4gICAgICBmb3IgKGNvbnN0IGZpeHR1cmVJZCBvZiBpbnNlcnRpb25PcmRlcikge1xuICAgICAgICBjb25zdCBmaXh0dXJlID0gZml4dHVyZXMuZmluZCgoZikgPT4gZi5maXh0dXJlSWQgPT09IGZpeHR1cmVJZCk7XG4gICAgICAgIGlmICghZml4dHVyZSkgY29udGludWU7XG5cbiAgICAgICAgY29uc3QgaGFzVGFyZ2V0ID0gISFmaXh0dXJlLnRhcmdldDtcbiAgICAgICAgY29uc3QgaGFzVW5pcXVlID0gISFmaXh0dXJlLnVuaXF1ZTtcbiAgICAgICAgY29uc3QgaGFzRHVwbGljYXRlID0gaGFzVGFyZ2V0IHx8IGhhc1VuaXF1ZTtcblxuICAgICAgICAvLyDspJHrs7XsnbQg7J6I6rOgIG92ZXJyaWRlPWZhbHNl7J24IOqyveyasDog7Iqk7YK1XG4gICAgICAgIGlmIChoYXNEdXBsaWNhdGUgJiYgIWZpeHR1cmUub3ZlcnJpZGUpIHtcbiAgICAgICAgICAvLyDquLDsobQg66CI7L2U65OcIElEIOyggOyepSAodW5pcXVlIOyasOyEoCwg7JeG7Jy866m0IHRhcmdldClcbiAgICAgICAgICBjb25zdCBleGlzdGluZ0lkID0gZml4dHVyZS51bmlxdWU/LmlkID8/IGZpeHR1cmUudGFyZ2V0Py5pZDtcbiAgICAgICAgICBhc3NlcnQoZXhpc3RpbmdJZCk7XG4gICAgICAgICAgdGhpcy5za2lwcGVkRml4dHVyZXMuc2V0KGZpeHR1cmVJZCwge1xuICAgICAgICAgICAgZW50aXR5SWQ6IGZpeHR1cmUuZW50aXR5SWQsXG4gICAgICAgICAgICBleGlzdGluZ0lkLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgIWlzVGVzdCgpICYmXG4gICAgICAgICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgICAgICAgY2hhbGsueWVsbG93KFxuICAgICAgICAgICAgICAgIGBTa2lwcGVkICR7Zml4dHVyZS5lbnRpdHlJZH0jJHtmaXh0dXJlLmlkfSAoZXhpc3Rpbmc6ICMke2V4aXN0aW5nSWR9LCBvdmVycmlkZTogZmFsc2UpYCxcbiAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gMy4g7YWM7J2067iU67OEIGZpeHR1cmUg6re466O57ZmUIChpbnNlcnRpb25PcmRlciDsiJzshJwg6riw67CYKVxuICAgICAgY29uc3QgZml4dHVyZXNCeVRhYmxlID0gbmV3IE1hcDxzdHJpbmcsIEZpeHR1cmVSZWNvcmRbXT4oKTtcbiAgICAgIGNvbnN0IHRhYmxlT3JkZXI6IHN0cmluZ1tdID0gW107XG5cbiAgICAgIGZvciAoY29uc3QgZml4dHVyZUlkIG9mIGluc2VydGlvbk9yZGVyKSB7XG4gICAgICAgIC8vIOyKpO2CteuQnCBmaXh0dXJlIOygnOyZuFxuICAgICAgICBpZiAodGhpcy5za2lwcGVkRml4dHVyZXMuaGFzKGZpeHR1cmVJZCkpIGNvbnRpbnVlO1xuXG4gICAgICAgIGNvbnN0IGZpeHR1cmUgPSBmaXh0dXJlcy5maW5kKChmKSA9PiBmLmZpeHR1cmVJZCA9PT0gZml4dHVyZUlkKTtcbiAgICAgICAgaWYgKCFmaXh0dXJlKSBjb250aW51ZTtcblxuICAgICAgICBjb25zdCBlbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChmaXh0dXJlLmVudGl0eUlkKTtcbiAgICAgICAgY29uc3QgdGFibGVOYW1lID0gZW50aXR5LnRhYmxlO1xuXG4gICAgICAgIGlmICghZml4dHVyZXNCeVRhYmxlLmhhcyh0YWJsZU5hbWUpKSB7XG4gICAgICAgICAgZml4dHVyZXNCeVRhYmxlLnNldCh0YWJsZU5hbWUsIFtdKTtcbiAgICAgICAgICB0YWJsZU9yZGVyLnB1c2godGFibGVOYW1lKTtcbiAgICAgICAgfVxuICAgICAgICBmaXh0dXJlc0J5VGFibGUuZ2V0KHRhYmxlTmFtZSk/LnB1c2goZml4dHVyZSk7XG4gICAgICB9XG5cbiAgICAgIGF3YWl0IGRiLnRyYW5zYWN0aW9uKGFzeW5jICh0cngpID0+IHtcbiAgICAgICAgY29uc3QgaW5zZXJ0ZWRJZHNCeVRhYmxlID0gbmV3IE1hcDxzdHJpbmcsIE1hcDxzdHJpbmcsIG51bWJlciB8IHN0cmluZz4+KCk7XG5cbiAgICAgICAgLy8gNC4g7YWM7J2067iU67OEIOugiOuyqOuzhCDsspjrpqxcbiAgICAgICAgZm9yIChjb25zdCB0YWJsZU5hbWUgb2YgdGFibGVPcmRlcikge1xuICAgICAgICAgIGNvbnN0IHRhYmxlRml4dHVyZXMgPSBmaXh0dXJlc0J5VGFibGUuZ2V0KHRhYmxlTmFtZSkgPz8gW107XG4gICAgICAgICAgY29uc3QgbGV2ZWxzID0gdGhpcy5ncm91cEZpeHR1cmVzQnlMZXZlbCh0YWJsZUZpeHR1cmVzKTtcblxuICAgICAgICAgIGZvciAoY29uc3QgbGV2ZWxGaXh0dXJlcyBvZiBsZXZlbHMpIHtcbiAgICAgICAgICAgIC8vIO2VtOuLuSDroIjrsqjsnZggZml4dHVyZeuTpCByZWdpc3RlclxuICAgICAgICAgICAgZm9yIChjb25zdCBmaXh0dXJlIG9mIGxldmVsRml4dHVyZXMpIHtcbiAgICAgICAgICAgICAgdGhpcy5yZWdpc3RlckZpeHR1cmUoZml4dHVyZSwgaW5zZXJ0ZWRJZHNCeVRhYmxlKTtcbiAgICAgICAgICAgICAgIWlzVGVzdCgpICYmXG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coXG4gICAgICAgICAgICAgICAgICBjaGFsay5ibHVlKFxuICAgICAgICAgICAgICAgICAgICBgUmVnaXN0ZXJlZCAke2ZpeHR1cmUuZW50aXR5SWR9IyR7Zml4dHVyZS5pZH0ke2ZpeHR1cmUub3ZlcnJpZGUgPyBgIChvdmVycmlkZSlgIDogXCJcIn1gLFxuICAgICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyB1cHNlcnQg7Iuk7ZaJIOyghCB1dWlkIOuqqeuhnSDsoIDsnqVcbiAgICAgICAgICAgIGNvbnN0IHRhYmxlID0gdGhpcy5idWlsZGVyLmdldFRhYmxlKHRhYmxlTmFtZSk7XG4gICAgICAgICAgICBjb25zdCB1dWlkcyA9IHRhYmxlLnJvd3MubWFwKChyb3cpID0+IHouc3RyaW5nKCkucGFyc2Uocm93LnV1aWQpKTtcblxuICAgICAgICAgICAgIWlzVGVzdCgpICYmXG4gICAgICAgICAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICAgICAgICAgIGNoYWxrLmJsdWUoXG4gICAgICAgICAgICAgICAgICBgVXBzZXJ0aW5nICR7dGFibGVOYW1lfSB3aXRoICR7dXVpZHMubGVuZ3RofSByb3dzIChsZXZlbCAke2xldmVscy5pbmRleE9mKGxldmVsRml4dHVyZXMpICsgMX0vJHtsZXZlbHMubGVuZ3RofSlgLFxuICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAvLyBTQUZFVFk6IHRhYmxlTmFtZeydgCDrk7HroZ3rkJwgRW50aXR57J2YIOyLpOygnCDthYzsnbTruJTrqoXsl5DshJzrp4wg7IOd7ISx65Cp64uI64ukLlxuICAgICAgICAgICAgY29uc3Qgc2NoZW1hVGFibGVOYW1lID0gdGFibGVOYW1lIGFzIGtleW9mIERhdGFiYXNlU2NoZW1hRXh0ZW5kO1xuICAgICAgICAgICAgY29uc3QgaWRzID0gZml4dHVyZVJlY29yZElkc1NjaGVtYS5wYXJzZShcbiAgICAgICAgICAgICAgYXdhaXQgdGhpcy5idWlsZGVyLnVwc2VydCh0cngsIHNjaGVtYVRhYmxlTmFtZSksXG4gICAgICAgICAgICApO1xuXG4gICAgICAgICAgICAvLyDsiJzshJwg6riw67CYIHV1aWQgLT4gaWQg66ek7ZWRXG4gICAgICAgICAgICAvLyBzZWxmLXJlZmVyZW5jZeqwgCDsl4bsnLzrr4DroZwg65Ox66GdIOyInOyEnCA9IOuwmO2ZmCDsiJzshJwg67O07J6lXG4gICAgICAgICAgICBpZiAodXVpZHMubGVuZ3RoID4gMCAmJiB1dWlkcy5sZW5ndGggPT09IGlkcy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgY29uc3QgZXhpc3RpbmdNYXAgPVxuICAgICAgICAgICAgICAgIGluc2VydGVkSWRzQnlUYWJsZS5nZXQodGFibGVOYW1lKSA/PyBuZXcgTWFwPHN0cmluZywgbnVtYmVyIHwgc3RyaW5nPigpO1xuICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHV1aWRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgZXhpc3RpbmdNYXAuc2V0KHV1aWRzW2ldLCBpZHNbaV0pO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGluc2VydGVkSWRzQnlUYWJsZS5zZXQodGFibGVOYW1lLCBleGlzdGluZ01hcCk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHV1aWRzLmxlbmd0aCAhPT0gaWRzLmxlbmd0aCkge1xuICAgICAgICAgICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgICAgICAgICAgY2hhbGsueWVsbG93KFxuICAgICAgICAgICAgICAgICAgYFdhcm5pbmc6IHV1aWQgY291bnQgKCR7dXVpZHMubGVuZ3RofSkgIT0gaWQgY291bnQgKCR7aWRzLmxlbmd0aH0pIGZvciAke3RhYmxlTmFtZX1gLFxuICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gNS4gTWFueVRvTWFueSDqtIDqs4Qg7LKY66asXG4gICAgICAgIGF3YWl0IHRoaXMucHJvY2Vzc01hbnlUb01hbnlSZWxhdGlvbnModHJ4LCBmaXh0dXJlcywgaW5zZXJ0ZWRJZHNCeVRhYmxlKTtcblxuICAgICAgICAvLyA2LiBQb3N0Z3JlU1FMIOyLnO2AgOyKpCDrpqzshYtcbiAgICAgICAgLy8gRml4dHVyZSDsgr3snoUg7ZuEIOqwgSDthYzsnbTruJTsnZggSUQg7Iuc7YCA7Iqk66W8IOy1nOuMgCBJRCDqsJLsnLzroZwg7JeF642w7J207Yq47ZWp64uI64ukLlxuICAgICAgICAvLyDsnbTroIfqsowg7ZWY7KeAIOyViuycvOuptCDri6TsnYwgSU5TRVJUIOyLnCBJROqwgCAyMDAw67KI64yA66GcIOyDneyEseuQoCDsiJgg7J6I7Iq164uI64ukLlxuICAgICAgICAhaXNUZXN0KCkgJiYgY29uc29sZS5sb2coY2hhbGsuYmx1ZShcIlJlc2V0dGluZyBzZXF1ZW5jZXMuLi5cIikpO1xuICAgICAgICBmb3IgKGNvbnN0IHRhYmxlTmFtZSBvZiB0YWJsZU9yZGVyKSB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIC8vIEVudGl0eeulvCDssL7slYTshJwgaWQg7YOA7J6FIO2ZleyduFxuICAgICAgICAgICAgY29uc3QgZW50aXR5ID0gRW50aXR5TWFuYWdlci5nZXRBbGxFbnRpdGllcygpLmZpbmQoXG4gICAgICAgICAgICAgIChlKSA9PiBlLnRhYmxlID09PSB0YWJsZU5hbWUgfHwgZS5pZC50b0xvd2VyQ2FzZSgpID09PSB0YWJsZU5hbWUsXG4gICAgICAgICAgICApO1xuXG4gICAgICAgICAgICBpZiAoZW50aXR5KSB7XG4gICAgICAgICAgICAgIGNvbnN0IGlkUHJvcCA9IGVudGl0eS5wcm9wcy5maW5kKChwKSA9PiBwLm5hbWUgPT09IFwiaWRcIik7XG4gICAgICAgICAgICAgIGNvbnN0IGlkVHlwZSA9IGlkUHJvcD8udHlwZTtcblxuICAgICAgICAgICAgICAvLyBpbnRlZ2VyL2JpZ0ludGVnZXLsnbTqsbDrgpgsIHN0cmluZ+ydtOyngOunjCBmaXh0dXJlU3RyYXRlZ3k9c2VxdWVuY2Xsnbgg6rK97Jqw7JeQ66eMIOumrOyFi+2VqeuLiOuLpFxuICAgICAgICAgICAgICBjb25zdCB1c2VzU2VxdWVuY2UgPVxuICAgICAgICAgICAgICAgIGlkVHlwZSA9PT0gXCJpbnRlZ2VyXCIgfHxcbiAgICAgICAgICAgICAgICBpZFR5cGUgPT09IFwiYmlnSW50ZWdlclwiIHx8XG4gICAgICAgICAgICAgICAgaWRQcm9wPy5jb25lPy5maXh0dXJlU3RyYXRlZ3kgPT09IFwic2VxdWVuY2VcIjtcblxuICAgICAgICAgICAgICBpZiAoIXVzZXNTZXF1ZW5jZSkge1xuICAgICAgICAgICAgICAgICFpc1Rlc3QoKSAmJlxuICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coXG4gICAgICAgICAgICAgICAgICAgIGNoYWxrLmdyYXkoXG4gICAgICAgICAgICAgICAgICAgICAgYFNraXBwZWQgc2VxdWVuY2UgcmVzZXQgZm9yICR7dGFibGVOYW1lfSAoaWQgdHlwZTogJHtpZFR5cGUgfHwgXCJ1bmtub3duXCJ9KWAsXG4gICAgICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIO2FjOydtOu4lOydmCDstZzrjIAgSUQg7KGw7ZqMIChzdHJpbmcg7YOA7J6F7J2AIOyIq+yekCDsupDsiqTtjIUg7ZWE7JqUKVxuICAgICAgICAgICAgY29uc3QgZW50aXR5MiA9IEVudGl0eU1hbmFnZXIuZ2V0QWxsRW50aXRpZXMoKS5maW5kKFxuICAgICAgICAgICAgICAoZSkgPT4gZS50YWJsZSA9PT0gdGFibGVOYW1lIHx8IGUuaWQudG9Mb3dlckNhc2UoKSA9PT0gdGFibGVOYW1lLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGNvbnN0IGlkVHlwZTIgPSBlbnRpdHkyPy5wcm9wcy5maW5kKChwKSA9PiBwLm5hbWUgPT09IFwiaWRcIik/LnR5cGU7XG4gICAgICAgICAgICBjb25zdCBtYXhJZFJlc3VsdCA9XG4gICAgICAgICAgICAgIGlkVHlwZTIgPT09IFwic3RyaW5nXCJcbiAgICAgICAgICAgICAgICA/IGF3YWl0IHRyeFxuICAgICAgICAgICAgICAgICAgICAucmF3KGBTRUxFQ1QgTUFYKGlkOjpiaWdpbnQpIGFzIG1heF9pZCBGUk9NIFwiJHt0YWJsZU5hbWV9XCJgKVxuICAgICAgICAgICAgICAgICAgICAudGhlbigocikgPT4gci5yb3dzWzBdKVxuICAgICAgICAgICAgICAgIDogYXdhaXQgdHJ4KHRhYmxlTmFtZSkubWF4KFwiaWQgYXMgbWF4X2lkXCIpLmZpcnN0KCk7XG4gICAgICAgICAgICBjb25zdCBtYXhJZCA9IG1heElkUmVzdWx0Py5tYXhfaWQ7XG5cbiAgICAgICAgICAgIGlmIChtYXhJZCAhPT0gbnVsbCAmJiBtYXhJZCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgIC8vIOyLnO2AgOyKpOuqheydhCBwZ19nZXRfc2VyaWFsX3NlcXVlbmNl66GcIOyViOyghO2VmOqyjCDsobDtmoxcbiAgICAgICAgICAgICAgYXdhaXQgdHJ4LnJhdyhgU0VMRUNUIHNldHZhbChwZ19nZXRfc2VyaWFsX3NlcXVlbmNlKD8sICdpZCcpLCA/KWAsIFtcbiAgICAgICAgICAgICAgICB0YWJsZU5hbWUsXG4gICAgICAgICAgICAgICAgbWF4SWQsXG4gICAgICAgICAgICAgIF0pO1xuICAgICAgICAgICAgICAhaXNUZXN0KCkgJiYgY29uc29sZS5sb2coY2hhbGsuZ3JlZW4oYFJlc2V0IHNlcXVlbmNlIGZvciAke3RhYmxlTmFtZX06ICR7bWF4SWR9YCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gY2F0Y2gge1xuICAgICAgICAgICAgLy8g7Iuc7YCA7Iqk6rCAIOyXhuuKlCDthYzsnbTruJQoam9pbiB0YWJsZSDrk7Ep7J2AIOustOyLnFxuICAgICAgICAgICAgIWlzVGVzdCgpICYmIGNvbnNvbGUubG9nKGNoYWxrLmdyYXkoYFNraXBwZWQgc2VxdWVuY2UgcmVzZXQgZm9yICR7dGFibGVOYW1lfWApKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyA3LiDqsrDqs7wg7IiY7KeRXG4gICAgICAgIGZvciAoY29uc3QgZml4dHVyZSBvZiBmaXh0dXJlcykge1xuICAgICAgICAgIGNvbnN0IGVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0KGZpeHR1cmUuZW50aXR5SWQpO1xuXG4gICAgICAgICAgLy8g7Iqk7YK165CcIGZpeHR1cmXripQg6riw7KG0IOugiOy9lOuTnCDsoJXrs7TroZwg6rKw6rO8IOy2lOqwgFxuICAgICAgICAgIGNvbnN0IHNraXBwZWQgPSB0aGlzLnNraXBwZWRGaXh0dXJlcy5nZXQoZml4dHVyZS5maXh0dXJlSWQpO1xuICAgICAgICAgIGlmIChza2lwcGVkKSB7XG4gICAgICAgICAgICByZXN1bHRzLnB1c2goe1xuICAgICAgICAgICAgICBlbnRpdHlJZDogZml4dHVyZS5lbnRpdHlJZCxcbiAgICAgICAgICAgICAgZGF0YTogYXdhaXQgdHJ4KGVudGl0eS50YWJsZSkud2hlcmUoXCJpZFwiLCBza2lwcGVkLmV4aXN0aW5nSWQpLmZpcnN0KCksXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnN0IHJlZiA9IHRoaXMuZml4dHVyZVJlZk1hcC5nZXQoZml4dHVyZS5maXh0dXJlSWQpO1xuICAgICAgICAgIGlmIChyZWYpIHtcbiAgICAgICAgICAgIGNvbnN0IHV1aWRUb0lkID0gaW5zZXJ0ZWRJZHNCeVRhYmxlLmdldChlbnRpdHkudGFibGUpO1xuICAgICAgICAgICAgY29uc3QgaW5zZXJ0ZWRJZCA9IHV1aWRUb0lkPy5nZXQocmVmLnV1aWQpO1xuXG4gICAgICAgICAgICBpZiAoaW5zZXJ0ZWRJZCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgIHJlc3VsdHMucHVzaCh7XG4gICAgICAgICAgICAgICAgZW50aXR5SWQ6IGZpeHR1cmUuZW50aXR5SWQsXG4gICAgICAgICAgICAgICAgZGF0YTogYXdhaXQgdHJ4KGVudGl0eS50YWJsZSkud2hlcmUoXCJpZFwiLCBpbnNlcnRlZElkKS5maXJzdCgpLFxuICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAhaXNUZXN0KCkgJiZcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgICAgICAgICAgIGNoYWxrLmdyZWVuKGBJbnNlcnRlZCBpbnRvICR7ZW50aXR5LnRhYmxlfTogIyR7Zml4dHVyZS5pZH0gLT4gIyR7aW5zZXJ0ZWRJZH1gKSxcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIGF3YWl0IGRiLmRlc3Ryb3koKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdW5pcXVlKHJlc3VsdHMsIChyKSA9PiBgJHtyLmVudGl0eUlkfSMke3IuZGF0YS5pZH1gKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGaXh0dXJlUmVjb3Jk66W8IFVwc2VydEJ1aWxkZXLsl5Ag65Ox66GdXG4gICAqIEBwYXJhbSBpbnNlcnRlZElkc0J5VGFibGUg7J2066+4IHVwc2VydOuQnCDthYzsnbTruJTsnZggdXVpZOKGkmlkIOunpO2VkSAo66CI67Ko67OEIOyymOumrCDsi5wg7IKs7JqpKVxuICAgKi9cbiAgcHJpdmF0ZSByZWdpc3RlckZpeHR1cmUoXG4gICAgZml4dHVyZTogRml4dHVyZVJlY29yZCxcbiAgICBpbnNlcnRlZElkc0J5VGFibGU/OiBNYXA8c3RyaW5nLCBNYXA8c3RyaW5nLCBudW1iZXIgfCBzdHJpbmc+PixcbiAgKTogVUJSZWYge1xuICAgIGNvbnN0IGVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0KGZpeHR1cmUuZW50aXR5SWQpO1xuICAgIGNvbnN0IHJvdzogVXBzZXJ0Um93ID0ge307XG5cbiAgICAvLyBPdmVycmlkZSDrqqjrk5wg7YyQ64uoOiB0YXJnZXQg65iQ64qUIHVuaXF1ZeqwgCDsnojqs6Agb3ZlcnJpZGU9dHJ1ZeyduCDqsr3smrBcbiAgICBjb25zdCBleGlzdGluZ1JlY29yZCA9IGZpeHR1cmUudGFyZ2V0ID8/IGZpeHR1cmUudW5pcXVlO1xuICAgIGNvbnN0IGlzT3ZlcnJpZGVNb2RlID0gZml4dHVyZS5vdmVycmlkZSAmJiBleGlzdGluZ1JlY29yZDtcblxuICAgIGZvciAoY29uc3QgW3Byb3BOYW1lLCBjb2x1bW5dIG9mIE9iamVjdC5lbnRyaWVzKGZpeHR1cmUuY29sdW1ucykpIHtcbiAgICAgIGNvbnN0IHByb3AgPSBjb2x1bW4ucHJvcDtcblxuICAgICAgaWYgKGlzVmlydHVhbFByb3AocHJvcCkpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIC8vIEdlbmVyYXRlZCBjb2x1bW7snYAgSU5TRVJU7JeQ7IScIOygnOyZuCAoRELqsIAg7J6Q64+ZIOyDneyEsSlcbiAgICAgIGlmIChcImdlbmVyYXRlZFwiIGluIHByb3AgJiYgcHJvcC5nZW5lcmF0ZWQpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIC8vIGlkIOyymOumrFxuICAgICAgaWYgKHByb3BOYW1lID09PSBcImlkXCIpIHtcbiAgICAgICAgY29uc3QgaWRQcm9wID0gZW50aXR5LnByb3BzLmZpbmQoKHApID0+IHAubmFtZSA9PT0gXCJpZFwiKTtcbiAgICAgICAgLy8gcGFyZW50SWQg7JeU7Yuw7Yuw7J2YIGlk64qUIOu2gOuqqCDsl5Tti7Dti7DsnZggRkvsnbTrr4DroZwg7Iuc7YCA7IqkIOuvuOyCrOyaqSAo66qF7Iuc7KCB7Jy866GcIO2PrO2VqClcbiAgICAgICAgY29uc3QgdXNlc1NlcXVlbmNlID1cbiAgICAgICAgICAhZW50aXR5LnBhcmVudElkICYmXG4gICAgICAgICAgKGlkUHJvcD8udHlwZSA9PT0gXCJpbnRlZ2VyXCIgfHxcbiAgICAgICAgICAgIGlkUHJvcD8udHlwZSA9PT0gXCJiaWdJbnRlZ2VyXCIgfHxcbiAgICAgICAgICAgIGlkUHJvcD8uY29uZT8uZml4dHVyZVN0cmF0ZWd5ID09PSBcInNlcXVlbmNlXCIpO1xuXG4gICAgICAgIGlmIChpc092ZXJyaWRlTW9kZSAmJiBleGlzdGluZ1JlY29yZCkge1xuICAgICAgICAgIC8vIE92ZXJyaWRlOiDquLDsobQg66CI7L2U65Oc7J2YIOqwkiDsgqzsmqkg4oaSIFVQREFURVxuICAgICAgICAgIHJvd1twcm9wTmFtZV0gPSBleGlzdGluZ1JlY29yZC5jb2x1bW5zW3Byb3BOYW1lXT8udmFsdWU7XG4gICAgICAgIH0gZWxzZSBpZiAoIXVzZXNTZXF1ZW5jZSkge1xuICAgICAgICAgIC8vIHN0cmluZyBQSyDrmJDripQgcGFyZW50SWQg7JeU7Yuw7YuwIEZLOiDsg53shLHrkJwgaWQg6rCS7J2EIElOU0VSVOyXkCDtj6ztlahcbiAgICAgICAgICByb3dbcHJvcE5hbWVdID0gY29sdW1uLnZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIC8vIGludGVnZXIvYmlnSW50ZWdlciBQSzogREIg7Iuc7YCA7Iqk7JeQIOunoeq5gCAo6rCSIOygnOyZuClcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGlmIChpc1JlbGF0aW9uUHJvcChwcm9wKSkge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgaXNCZWxvbmdzVG9PbmVSZWxhdGlvblByb3AocHJvcCkgfHxcbiAgICAgICAgICAoaXNPbmVUb09uZVJlbGF0aW9uUHJvcChwcm9wKSAmJiBwcm9wLmhhc0pvaW5Db2x1bW4pXG4gICAgICAgICkge1xuICAgICAgICAgIGNvbnN0IHJlbGF0ZWRJZCA9IHJlbGF0aW9uSWRTY2hlbWEucGFyc2UoY29sdW1uLnZhbHVlKTtcbiAgICAgICAgICBpZiAocmVsYXRlZElkICE9PSBudWxsICYmIHJlbGF0ZWRJZCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBjb25zdCByZWxhdGVkRml4dHVyZUlkID0gYCR7cHJvcC53aXRofSMke3JlbGF0ZWRJZH1gO1xuXG4gICAgICAgICAgICAvLyDrqLzsoIAgc2tpcOuQnCBmaXh0dXJl7J247KeAIO2ZleyduFxuICAgICAgICAgICAgY29uc3Qgc2tpcHBlZEV4aXN0aW5nSWQgPSB0aGlzLnNraXBwZWRGaXh0dXJlcy5nZXQocmVsYXRlZEZpeHR1cmVJZCk/LmV4aXN0aW5nSWQ7XG4gICAgICAgICAgICBpZiAoc2tpcHBlZEV4aXN0aW5nSWQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAvLyBza2lw65CcIGZpeHR1cmUg4oaSIHRhcmdldCBEQuydmCDquLDsobQg66CI7L2U65OcIGlkIOyCrOyaqVxuICAgICAgICAgICAgICByb3dbYCR7cHJvcE5hbWV9X2lkYF0gPSBza2lwcGVkRXhpc3RpbmdJZDtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGNvbnN0IHJlbGF0ZWRSZWYgPSB0aGlzLmZpeHR1cmVSZWZNYXAuZ2V0KHJlbGF0ZWRGaXh0dXJlSWQpO1xuICAgICAgICAgICAgICBpZiAocmVsYXRlZFJlZikge1xuICAgICAgICAgICAgICAgIC8vIOydtOuvuCB1cHNlcnTrkJwg6rCZ7J2AIO2FjOydtOu4lCBmaXh0dXJlIO2ZleyduFxuICAgICAgICAgICAgICAgIGNvbnN0IHJlbGF0ZWRFbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChwcm9wLndpdGgpO1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlbGF0ZWRJbnNlcnRlZElkcyA9IGluc2VydGVkSWRzQnlUYWJsZT8uZ2V0KHJlbGF0ZWRFbnRpdHkudGFibGUpO1xuICAgICAgICAgICAgICAgIGNvbnN0IGFjdHVhbElkID0gcmVsYXRlZEluc2VydGVkSWRzPy5nZXQocmVsYXRlZFJlZi51dWlkKTtcblxuICAgICAgICAgICAgICAgIGlmIChhY3R1YWxJZCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAvLyDsnbTrr7ggdXBzZXJ065CoIOKGkiDsi6TsoJwgSUQg7IKs7JqpXG4gICAgICAgICAgICAgICAgICByb3dbYCR7cHJvcE5hbWV9X2lkYF0gPSBhY3R1YWxJZDtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgLy8g7JWE7KeBIHVwc2VydCDslYjrkKgg4oaSIFVCUmVmIOyCrOyaqVxuICAgICAgICAgICAgICAgICAgcm93W2Ake3Byb3BOYW1lfV9pZGBdID0gcmVsYXRlZFJlZjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gZml4dHVyZXPsl5Ag7Y+s7ZWo65CY7KeAIOyViuydgCDroIjsvZTrk5wg4oaSIElEIOq3uOuMgOuhnCDsgqzsmqlcbiAgICAgICAgICAgICAgICByb3dbYCR7cHJvcE5hbWV9X2lkYF0gPSByZWxhdGVkSWQ7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcm93W2Ake3Byb3BOYW1lfV9pZGBdID0gbnVsbDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gSGFzTWFueSwgTWFueVRvTWFueeuKlCDrs4Trj4Qg7LKY66asXG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyDsnbzrsJgg7Lus65+8XG4gICAgICAgIHJvd1twcm9wTmFtZV0gPSB0aGlzLmNvbnZlcnRDb2x1bW5WYWx1ZShwcm9wLCBjb2x1bW4udmFsdWUpO1xuICAgICAgfVxuICAgIH1cblxuICAgICFpc1Rlc3QoKSAmJlxuICAgICAgY29uc29sZS5sb2coY2hhbGsuYmx1ZShgUmVnaXN0ZXJpbmcgJHtlbnRpdHkudGFibGV9IC0gJHtpbnNwZWN0KHJvdywgZmFsc2UsIG51bGwsIHRydWUpfWApKTtcbiAgICBjb25zdCByZWYgPSB0aGlzLmJ1aWxkZXIucmVnaXN0ZXIoZW50aXR5LnRhYmxlLCByb3cpO1xuICAgIHRoaXMuZml4dHVyZVJlZk1hcC5zZXQoZml4dHVyZS5maXh0dXJlSWQsIHJlZik7XG5cbiAgICByZXR1cm4gcmVmO1xuICB9XG5cbiAgLyoqXG4gICAqIOy7rOufvCDqsJIg67OA7ZmYXG4gICAqL1xuICBwcml2YXRlIGNvbnZlcnRDb2x1bW5WYWx1ZShcbiAgICBwcm9wOiBFbnRpdHlQcm9wLFxuICAgIHZhbHVlOiBGaXh0dXJlUmVjb3JkW1wiY29sdW1uc1wiXVtzdHJpbmddW1widmFsdWVcIl0sXG4gICk6IERhdGFFeHBsb3JlclZhbHVlIHtcbiAgICBpZiAodmFsdWUgPT09IG51bGwgfHwgdmFsdWUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgc3dpdGNoIChwcm9wLnR5cGUpIHtcbiAgICAgIGNhc2UgXCJqc29uXCI6XG4gICAgICAgIC8vIFVwc2VydEJ1aWxkZXIucmVnaXN0ZXLsl5DshJwgSlNPTi5zdHJpbmdpZnkg7LKY66as7ZWY66+A66GcIG9iamVjdCDqt7jrjIDroZwg7KCE64usXG4gICAgICAgIHJldHVybiB2YWx1ZTtcblxuICAgICAgY2FzZSBcImRhdGVcIjpcbiAgICAgICAge1xuICAgICAgICAgIGNvbnN0IGRhdGVTb3VyY2UgPSB6LnVuaW9uKFt6LnN0cmluZygpLCB6Lm51bWJlcigpXSkuc2FmZVBhcnNlKHZhbHVlKTtcbiAgICAgICAgICBpZiAoZGF0ZVNvdXJjZS5zdWNjZXNzKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IERhdGUoZGF0ZVNvdXJjZS5kYXRhKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHZhbHVlO1xuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBwcm9jZXNzTWFueVRvTWFueVJlbGF0aW9ucyhcbiAgICB0cng6IEtuZXguVHJhbnNhY3Rpb24sXG4gICAgZml4dHVyZXM6IEZpeHR1cmVSZWNvcmRbXSxcbiAgICBpbnNlcnRlZElkc0J5VGFibGU6IE1hcDxzdHJpbmcsIE1hcDxzdHJpbmcsIG51bWJlciB8IHN0cmluZz4+LFxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBmb3IgKGNvbnN0IGZpeHR1cmUgb2YgZml4dHVyZXMpIHtcbiAgICAgIGNvbnN0IGVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0KGZpeHR1cmUuZW50aXR5SWQpO1xuICAgICAgY29uc3Qgc291cmNlUmVmID0gdGhpcy5maXh0dXJlUmVmTWFwLmdldChmaXh0dXJlLmZpeHR1cmVJZCk7XG5cbiAgICAgIGlmICghc291cmNlUmVmKSBjb250aW51ZTtcblxuICAgICAgY29uc3Qgc291cmNlVXVpZFRvSWQgPSBpbnNlcnRlZElkc0J5VGFibGUuZ2V0KGVudGl0eS50YWJsZSk7XG4gICAgICBjb25zdCBzb3VyY2VJZCA9IHNvdXJjZVV1aWRUb0lkPy5nZXQoc291cmNlUmVmLnV1aWQpO1xuXG4gICAgICBpZiAoc291cmNlSWQgPT09IHVuZGVmaW5lZCkgY29udGludWU7XG5cbiAgICAgIGZvciAoY29uc3QgWywgY29sdW1uXSBvZiBPYmplY3QuZW50cmllcyhmaXh0dXJlLmNvbHVtbnMpKSB7XG4gICAgICAgIGNvbnN0IHByb3AgPSBjb2x1bW4ucHJvcDtcblxuICAgICAgICBpZiAoaXNNYW55VG9NYW55UmVsYXRpb25Qcm9wKHByb3ApICYmIEFycmF5LmlzQXJyYXkoY29sdW1uLnZhbHVlKSkge1xuICAgICAgICAgIC8vIOyEoO2DneuQmOyngCDslYrsnYAgTWFueVRvTWFueSDqtIDqs4TripQg7KCA7J6l7ZWY7KeAIOyViuydjFxuICAgICAgICAgIGNvbnN0IHRhcmdldFRhYmxlID0gRW50aXR5TWFuYWdlci5nZXQocHJvcC53aXRoKTtcbiAgICAgICAgICBpZiAoIXRoaXMuYnVpbGRlci5oYXNUYWJsZSh0YXJnZXRUYWJsZS50YWJsZSkpIGNvbnRpbnVlO1xuXG4gICAgICAgICAgY29uc3QgcmVsYXRlZElkcyA9IGZpeHR1cmVSZWNvcmRJZHNTY2hlbWEucGFyc2UoY29sdW1uLnZhbHVlKTtcbiAgICAgICAgICBpZiAocmVsYXRlZElkcy5sZW5ndGggPT09IDApIGNvbnRpbnVlO1xuXG4gICAgICAgICAgY29uc3Qgam9pblRhYmxlID0gcHJvcC5qb2luVGFibGU7XG4gICAgICAgICAgY29uc3QgcmVsYXRlZEVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0KHByb3Aud2l0aCk7XG5cbiAgICAgICAgICBjb25zdCBzb3VyY2VDb2x1bW4gPSBgJHtpbmZsZWN0aW9uLnNpbmd1bGFyaXplKGVudGl0eS50YWJsZSl9X2lkYDtcbiAgICAgICAgICBjb25zdCB0YXJnZXRDb2x1bW4gPSBgJHtpbmZsZWN0aW9uLnNpbmd1bGFyaXplKHJlbGF0ZWRFbnRpdHkudGFibGUpfV9pZGA7XG5cbiAgICAgICAgICBmb3IgKGNvbnN0IHJlbGF0ZWRJZCBvZiByZWxhdGVkSWRzKSB7XG4gICAgICAgICAgICBjb25zdCByZWxhdGVkRml4dHVyZUlkID0gYCR7cHJvcC53aXRofSMke3JlbGF0ZWRJZH1gO1xuICAgICAgICAgICAgY29uc3QgcmVsYXRlZFJlZiA9IHRoaXMuZml4dHVyZVJlZk1hcC5nZXQocmVsYXRlZEZpeHR1cmVJZCk7XG5cbiAgICAgICAgICAgIGxldCB0YXJnZXRJZDogbnVtYmVyIHwgc3RyaW5nO1xuXG4gICAgICAgICAgICBpZiAocmVsYXRlZFJlZikge1xuICAgICAgICAgICAgICBjb25zdCByZWxhdGVkVXVpZFRvSWQgPSBpbnNlcnRlZElkc0J5VGFibGUuZ2V0KHJlbGF0ZWRFbnRpdHkudGFibGUpO1xuICAgICAgICAgICAgICBjb25zdCByZXNvbHZlZElkID0gcmVsYXRlZFV1aWRUb0lkPy5nZXQocmVsYXRlZFJlZi51dWlkKTtcblxuICAgICAgICAgICAgICBpZiAocmVzb2x2ZWRJZCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICAgICAgICAgICAgYFJlbGF0ZWQgZml4dHVyZSAke3JlbGF0ZWRGaXh0dXJlSWR9IG5vdCBmb3VuZCBpbiBpbnNlcnRlZElkcywgc2tpcHBpbmdgLFxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgdGFyZ2V0SWQgPSByZXNvbHZlZElkO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgdGFyZ2V0SWQgPSByZWxhdGVkSWQ7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIEpvaW5UYWJsZeyXkCDsgr3snoVcbiAgICAgICAgICAgIGNvbnN0IFtmb3VuZF0gPSBhd2FpdCB0cngoam9pblRhYmxlKVxuICAgICAgICAgICAgICAud2hlcmUoe1xuICAgICAgICAgICAgICAgIFtzb3VyY2VDb2x1bW5dOiBzb3VyY2VJZCxcbiAgICAgICAgICAgICAgICBbdGFyZ2V0Q29sdW1uXTogdGFyZ2V0SWQsXG4gICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgIC5saW1pdCgxKTtcblxuICAgICAgICAgICAgaWYgKCFmb3VuZCkge1xuICAgICAgICAgICAgICBhd2FpdCB0cngoam9pblRhYmxlKS5pbnNlcnQoe1xuICAgICAgICAgICAgICAgIFtzb3VyY2VDb2x1bW5dOiBzb3VyY2VJZCxcbiAgICAgICAgICAgICAgICBbdGFyZ2V0Q29sdW1uXTogdGFyZ2V0SWQsXG4gICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICFpc1Rlc3QoKSAmJlxuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICAgICAgICAgICAgY2hhbGsuZ3JlZW4oXG4gICAgICAgICAgICAgICAgICAgIGBJbnNlcnRlZCBpbnRvICR7am9pblRhYmxlfTogJHtlbnRpdHkudGFibGV9KCR7c291cmNlSWR9KSAtICR7cmVsYXRlZEVudGl0eS50YWJsZX0oJHt0YXJnZXRJZH0pYCxcbiAgICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICog6rCZ7J2AIO2FjOydtOu4lCDrgrQgZml4dHVyZeuTpOydhCBzZWxmLXJlZmVyZW5jZSDroIjrsqjrs4TroZwg67aE7ZWgXG4gICAqIC0gc2VsZi1yZWZlcmVuY2XqsIAg7JeG64qUIGZpeHR1cmXrk6Q6IExldmVsIDBcbiAgICogLSBMZXZlbCAw7J2EIOywuOyhsO2VmOuKlCBmaXh0dXJl65OkOiBMZXZlbCAxXG4gICAqIC0g67CY67O1XG4gICAqXG4gICAqIFVwc2VydEJ1aWxkZXLqsIAgc2VsZi1yZWZlcmVuY2XqsIAg7J6I7Jy866m0IGJ1aWxkSW5zZXJ0TGV2ZWxzKCnroZwg7J6s7KCV66Cs7ZWY7JesXG4gICAqIOuTseuhnSDsiJzshJzsmYAg67CY7ZmYIOyInOyEnOqwgCDri6zrnbzsp4gg7IiYIOyeiOyKteuLiOuLpC5cbiAgICog7J2066W8IOuwqeyngO2VmOq4sCDsnITtlbQgRml4dHVyZU1hbmFnZXLqsIAg66CI67Ko67OE66GcIOuCmOuIoOyEnCDsspjrpqztlanri4jri6QuXG4gICAqL1xuICBwcml2YXRlIGdyb3VwRml4dHVyZXNCeUxldmVsKGZpeHR1cmVzOiBGaXh0dXJlUmVjb3JkW10pOiBGaXh0dXJlUmVjb3JkW11bXSB7XG4gICAgaWYgKGZpeHR1cmVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIFtdO1xuICAgIH1cblxuICAgIGNvbnN0IGVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0KGZpeHR1cmVzWzBdLmVudGl0eUlkKTtcblxuICAgIC8vIHNlbGYtcmVmZXJlbmNlIHJlbGF0aW9uIHByb3Ag7LC+6riwXG4gICAgY29uc3Qgc2VsZlJlZlByb3BzID0gZW50aXR5LnByb3BzLmZpbHRlcihcbiAgICAgIChwKTogcCBpcyBCZWxvbmdzVG9PbmVSZWxhdGlvblByb3AgfCBPbmVUb09uZVJlbGF0aW9uUHJvcCA9PlxuICAgICAgICBpc1JlbGF0aW9uUHJvcChwKSAmJlxuICAgICAgICAoaXNCZWxvbmdzVG9PbmVSZWxhdGlvblByb3AocCkgfHwgKGlzT25lVG9PbmVSZWxhdGlvblByb3AocCkgJiYgcC5oYXNKb2luQ29sdW1uKSkgJiZcbiAgICAgICAgcC53aXRoID09PSBlbnRpdHkuaWQsXG4gICAgKTtcblxuICAgIGlmIChzZWxmUmVmUHJvcHMubGVuZ3RoID09PSAwKSB7XG4gICAgICAvLyBzZWxmLXJlZmVyZW5jZSDsl4bsnYwg4oaSIOuLqOydvCDroIjrsqhcbiAgICAgIHJldHVybiBbZml4dHVyZXNdO1xuICAgIH1cblxuICAgIC8vIOugiOuyqOuzhCDrtoTtlaAgKHRvcG9sb2dpY2FsIHNvcnQpXG4gICAgY29uc3QgbGV2ZWxzOiBGaXh0dXJlUmVjb3JkW11bXSA9IFtdO1xuICAgIGNvbnN0IHJlbWFpbmluZyA9IG5ldyBTZXQoZml4dHVyZXMubWFwKChmKSA9PiBmLmZpeHR1cmVJZCkpO1xuICAgIGNvbnN0IHByb2Nlc3NlZCA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuXG4gICAgd2hpbGUgKHJlbWFpbmluZy5zaXplID4gMCkge1xuICAgICAgY29uc3QgY3VycmVudExldmVsOiBGaXh0dXJlUmVjb3JkW10gPSBbXTtcblxuICAgICAgZm9yIChjb25zdCBmaXh0dXJlIG9mIGZpeHR1cmVzKSB7XG4gICAgICAgIGlmICghcmVtYWluaW5nLmhhcyhmaXh0dXJlLmZpeHR1cmVJZCkpIGNvbnRpbnVlO1xuXG4gICAgICAgIC8vIHNlbGYtcmVmZXJlbmNl6rCAIOuqqOuRkCDsnbTrr7gg7LKY66as65CQ6rGw64KYIG51bGzsnbgg6rK97JqwXG4gICAgICAgIGNvbnN0IGNhblByb2Nlc3MgPSBzZWxmUmVmUHJvcHMuZXZlcnkoKHByb3ApID0+IHtcbiAgICAgICAgICBjb25zdCByZWZJZCA9IHJlbGF0aW9uSWRTY2hlbWEucGFyc2UoZml4dHVyZS5jb2x1bW5zW3Byb3AubmFtZV0/LnZhbHVlKTtcbiAgICAgICAgICBpZiAocmVmSWQgPT09IG51bGwgfHwgcmVmSWQgPT09IHVuZGVmaW5lZCkgcmV0dXJuIHRydWU7XG4gICAgICAgICAgY29uc3QgcmVmRml4dHVyZUlkID0gYCR7cHJvcC53aXRofSMke3JlZklkfWA7XG4gICAgICAgICAgLy8g7J2066+4IOyymOumrOuQkOqxsOuCmCwg7ZiE7J6sIGZpeHR1cmVz7JeQIO2PrO2VqOuQmOyngCDslYrsnYAg6rK97JqwICjsmbjrtoAg7LC47KGwKVxuICAgICAgICAgIHJldHVybiBwcm9jZXNzZWQuaGFzKHJlZkZpeHR1cmVJZCkgfHwgIXJlbWFpbmluZy5oYXMocmVmRml4dHVyZUlkKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaWYgKGNhblByb2Nlc3MpIHtcbiAgICAgICAgICBjdXJyZW50TGV2ZWwucHVzaChmaXh0dXJlKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoY3VycmVudExldmVsLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICBjb25zdCByZW1haW5pbmdJZHMgPSBBcnJheS5mcm9tKHJlbWFpbmluZykuam9pbihcIiwgXCIpO1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgYENpcmN1bGFyIHNlbGYtcmVmZXJlbmNlIGRldGVjdGVkIGluICR7ZW50aXR5LnRhYmxlfS4gUmVtYWluaW5nIGZpeHR1cmVzOiAke3JlbWFpbmluZ0lkc31gLFxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICBmb3IgKGNvbnN0IGZpeHR1cmUgb2YgY3VycmVudExldmVsKSB7XG4gICAgICAgIHJlbWFpbmluZy5kZWxldGUoZml4dHVyZS5maXh0dXJlSWQpO1xuICAgICAgICBwcm9jZXNzZWQuYWRkKGZpeHR1cmUuZml4dHVyZUlkKTtcbiAgICAgIH1cblxuICAgICAgbGV2ZWxzLnB1c2goY3VycmVudExldmVsKTtcbiAgICB9XG5cbiAgICByZXR1cm4gbGV2ZWxzO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBjaGVja1VuaXF1ZVZpb2xhdGlvbihkYjogS25leCwgZW50aXR5OiBFbnRpdHksIGZpeHR1cmU6IEZpeHR1cmVSZWNvcmQpIHtcbiAgICBjb25zdCBlbnRpdHlVbmlxdWVJbmRleGVzID0gZW50aXR5LmluZGV4ZXM/LmZpbHRlcigoaSkgPT4gaS50eXBlID09PSBcInVuaXF1ZVwiKSA/PyBbXTtcblxuICAgIGNvbnN0IHVuaXF1ZUluZGV4ZXMgPSBlbnRpdHlVbmlxdWVJbmRleGVzLmZpbHRlcigoaW5kZXgpID0+XG4gICAgICBpbmRleC5jb2x1bW5zLmV2ZXJ5KChjb2x1bW4pID0+ICFjb2x1bW4ubmFtZS5zdGFydHNXaXRoKGAke2VudGl0eS50YWJsZX1fX2ApKSxcbiAgICApO1xuICAgIGlmICh1bmlxdWVJbmRleGVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgbGV0IHVuaXF1ZVF1ZXJ5ID0gZGIoZW50aXR5LnRhYmxlKTtcbiAgICBsZXQgaGFzQ29uZGl0aW9uID0gZmFsc2U7XG5cbiAgICBmb3IgKGNvbnN0IGluZGV4IG9mIHVuaXF1ZUluZGV4ZXMpIHtcbiAgICAgIC8vIOy7rOufvCDspJEg7ZWY64KY652864+EIG51bGzsnbTrqbQg7Jyg64uI7YGsIOygnOyVveydhCDsnITrsJjtlZjsp4Ag7JWK6riwIOuVjOusuOyXkCDtlbTri7kg7J24642x7Iqk64qUIOustOyLnFxuICAgICAgY29uc3QgY29udGFpbnNOdWxsID0gaW5kZXguY29sdW1ucy5zb21lKChjb2x1bW4pID0+IHtcbiAgICAgICAgY29uc3QgZmllbGQgPSBjb2x1bW4ubmFtZS5yZXBsYWNlKC9faWQkLywgXCJcIik7XG4gICAgICAgIHJldHVybiBmaXh0dXJlLmNvbHVtbnNbZmllbGRdPy52YWx1ZSA9PT0gbnVsbDtcbiAgICAgIH0pO1xuICAgICAgaWYgKGNvbnRhaW5zTnVsbCkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgdW5pcXVlUXVlcnkgPSB1bmlxdWVRdWVyeS5vcldoZXJlKChxYikgPT4ge1xuICAgICAgICBmb3IgKGNvbnN0IGNvbHVtbiBvZiBpbmRleC5jb2x1bW5zKSB7XG4gICAgICAgICAgY29uc3QgZmllbGQgPSBjb2x1bW4ubmFtZS5yZXBsYWNlKC9faWQkLywgXCJcIik7XG5cbiAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShmaXh0dXJlLmNvbHVtbnNbZmllbGRdPy52YWx1ZSkpIHtcbiAgICAgICAgICAgIHFiLndoZXJlSW4oY29sdW1uLm5hbWUsIGZpeHR1cmUuY29sdW1uc1tmaWVsZF0udmFsdWUpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBxYi5hbmRXaGVyZShjb2x1bW4ubmFtZSwgZml4dHVyZS5jb2x1bW5zW2ZpZWxkXT8udmFsdWUpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICBoYXNDb25kaXRpb24gPSB0cnVlO1xuICAgIH1cblxuICAgIGlmICghaGFzQ29uZGl0aW9uKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBjb25zdCBbdW5pcXVlRm91bmRdID0gYXdhaXQgdW5pcXVlUXVlcnk7XG4gICAgcmV0dXJuIHVuaXF1ZUZvdW5kO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBjaGVja0R1cGxpY2F0ZUJ5Q29sdW1ucyhcbiAgICBkYjogS25leCxcbiAgICBlbnRpdHk6IEVudGl0eSxcbiAgICBmaXh0dXJlOiBGaXh0dXJlUmVjb3JkLFxuICAgIGNvbHVtbnM6IHN0cmluZ1tdLFxuICApIHtcbiAgICBpZiAoY29sdW1ucy5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIGNvbnN0IHdoZXJlQ2xhdXNlOiBEYXRhRXhwbG9yZXJSZWNvcmQgPSB7fTtcblxuICAgIGZvciAoY29uc3QgY29sdW1uIG9mIGNvbHVtbnMpIHtcbiAgICAgIC8vIHJlbGF0aW9uIO2VhOuTnOyduCDqsr3smrAgX2lkIOu2meydtOq4sFxuICAgICAgY29uc3QgcHJvcCA9IGVudGl0eS5wcm9wcy5maW5kKChwKSA9PiBwLm5hbWUgPT09IGNvbHVtbik7XG4gICAgICBjb25zdCBkYkNvbHVtbiA9IHByb3AgJiYgaXNSZWxhdGlvblByb3AocHJvcCkgPyBgJHtjb2x1bW59X2lkYCA6IGNvbHVtbjtcbiAgICAgIGNvbnN0IHZhbHVlID0gZml4dHVyZS5jb2x1bW5zW2NvbHVtbl0/LnZhbHVlO1xuXG4gICAgICAvLyBudWxsIOqwkuydtCDtj6ztlajrkJwg6rK97JqwIOykkeuztSDtmZXsnbgg7Iqk7YK1XG4gICAgICBpZiAodmFsdWUgPT09IG51bGwgfHwgdmFsdWUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cblxuICAgICAgd2hlcmVDbGF1c2VbZGJDb2x1bW5dID0gdmFsdWU7XG4gICAgfVxuXG4gICAgY29uc3QgW2ZvdW5kXSA9IGF3YWl0IGRiKGVudGl0eS50YWJsZSkud2hlcmUod2hlcmVDbGF1c2UpLmxpbWl0KDEpO1xuICAgIHJldHVybiBmb3VuZDtcbiAgfVxuXG4gIGFzeW5jIGFkZEZpeHR1cmVMb2FkZXIoY29kZTogc3RyaW5nKSB7XG4gICAgY29uc3QgcGF0aCA9IGAke1NvbmFtdS5hcGlSb290UGF0aH0vc3JjL3Rlc3RpbmcvZml4dHVyZS50c2A7XG4gICAgY29uc3QgY29udGVudCA9IHJlYWRGaWxlU3luYyhwYXRoKS50b1N0cmluZygpO1xuXG4gICAgY29uc3QgZml4dHVyZUxvYWRlclN0YXJ0ID0gY29udGVudC5pbmRleE9mKFwiY29uc3QgZml4dHVyZUxvYWRlciA9IHtcIik7XG4gICAgY29uc3QgZml4dHVyZUxvYWRlckVuZCA9IGNvbnRlbnQuaW5kZXhPZihcIn07XCIsIGZpeHR1cmVMb2FkZXJTdGFydCk7XG5cbiAgICBpZiAoZml4dHVyZUxvYWRlclN0YXJ0ICE9PSAtMSAmJiBmaXh0dXJlTG9hZGVyRW5kICE9PSAtMSkge1xuICAgICAgY29uc3QgbmV3Q29udGVudCA9IGAke2NvbnRlbnQuc2xpY2UoMCwgZml4dHVyZUxvYWRlckVuZCl9ICAke2NvZGV9XFxuJHtjb250ZW50LnNsaWNlKGZpeHR1cmVMb2FkZXJFbmQpfWA7XG5cbiAgICAgIHdyaXRlRmlsZVN5bmMocGF0aCwgbmV3Q29udGVudCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkZhaWxlZCB0byBmaW5kIGZpeHR1cmVMb2FkZXIgaW4gZml4dHVyZS50c1wiKTtcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IEZpeHR1cmVNYW5hZ2VyID0gbmV3IEZpeHR1cmVNYW5hZ2VyQ2xhc3MoKTtcbiJdLCJtYXBwaW5ncyI6Ijs7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
|