sonamu 0.5.7 → 0.7.0
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/.swcrc.project-default +18 -0
- package/bin/cli.js +24 -0
- package/dist/ai/agents/agent.d.ts +11 -0
- package/dist/ai/agents/agent.d.ts.map +1 -0
- package/dist/ai/agents/agent.js +65 -0
- package/dist/ai/agents/index.d.ts +3 -0
- package/dist/ai/agents/index.d.ts.map +1 -0
- package/dist/ai/agents/index.js +4 -0
- package/dist/ai/agents/types.d.ts +43 -0
- package/dist/ai/agents/types.d.ts.map +1 -0
- package/dist/ai/agents/types.js +3 -0
- package/dist/ai/index.d.ts +2 -0
- package/dist/ai/index.d.ts.map +1 -0
- package/dist/ai/index.js +3 -0
- package/dist/ai/providers/rtzr/api.d.ts +22 -0
- package/dist/ai/providers/rtzr/api.d.ts.map +1 -0
- package/dist/ai/providers/rtzr/api.js +28 -0
- package/dist/ai/providers/rtzr/error.d.ts +18 -0
- package/dist/ai/providers/rtzr/error.d.ts.map +1 -0
- package/dist/ai/providers/rtzr/error.js +29 -0
- package/dist/ai/providers/rtzr/index.d.ts +5 -0
- package/dist/ai/providers/rtzr/index.d.ts.map +1 -0
- package/dist/ai/providers/rtzr/index.js +6 -0
- package/dist/ai/providers/rtzr/model.d.ts +52 -0
- package/dist/ai/providers/rtzr/model.d.ts.map +1 -0
- package/dist/ai/providers/rtzr/model.js +137 -0
- package/dist/ai/providers/rtzr/options.d.ts +7 -0
- package/dist/ai/providers/rtzr/options.d.ts.map +1 -0
- package/dist/ai/providers/rtzr/options.js +47 -0
- package/dist/ai/providers/rtzr/provider.d.ts +18 -0
- package/dist/ai/providers/rtzr/provider.d.ts.map +1 -0
- package/dist/ai/providers/rtzr/provider.js +54 -0
- package/dist/ai/providers/rtzr/utils.d.ts +19 -0
- package/dist/ai/providers/rtzr/utils.d.ts.map +1 -0
- package/dist/ai/providers/rtzr/utils.js +88 -0
- package/dist/api/base-frame.d.ts +2 -2
- package/dist/api/base-frame.d.ts.map +1 -1
- package/dist/api/base-frame.js +13 -2
- package/dist/api/caster.d.ts.map +1 -1
- package/dist/api/caster.js +71 -2
- package/dist/api/code-converters.d.ts +58 -14
- package/dist/api/code-converters.d.ts.map +1 -1
- package/dist/api/code-converters.js +258 -2
- package/dist/api/config.d.ts +90 -0
- package/dist/api/config.d.ts.map +1 -0
- package/dist/api/config.js +25 -0
- package/dist/api/context.d.ts +4 -2
- package/dist/api/context.d.ts.map +1 -1
- package/dist/api/context.js +3 -2
- package/dist/api/decorators.d.ts +20 -6
- package/dist/api/decorators.d.ts.map +1 -1
- package/dist/api/decorators.js +235 -2
- package/dist/api/index.d.ts +2 -2
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/index.js +9 -2
- package/dist/api/sonamu.d.ts +10 -24
- package/dist/api/sonamu.d.ts.map +1 -1
- package/dist/api/sonamu.js +514 -2
- package/dist/api/validator.d.ts +6 -0
- package/dist/api/validator.d.ts.map +1 -0
- package/dist/api/validator.js +81 -0
- package/dist/bin/build-config.d.ts +6 -1
- package/dist/bin/build-config.d.ts.map +1 -1
- package/dist/bin/build-config.js +15 -2
- package/dist/bin/cli.js +519 -2
- package/dist/bin/hot-hook-register.d.ts +11 -0
- package/dist/bin/hot-hook-register.d.ts.map +1 -0
- package/dist/bin/hot-hook-register.js +21 -0
- package/dist/bin/loader-register.d.ts +2 -0
- package/dist/bin/loader-register.d.ts.map +1 -0
- package/dist/bin/loader-register.js +34 -0
- package/dist/database/_batch_update.d.ts +5 -3
- package/dist/database/_batch_update.d.ts.map +1 -1
- package/dist/database/_batch_update.js +95 -2
- package/dist/database/base-model.d.ts +96 -10
- package/dist/database/base-model.d.ts.map +1 -1
- package/dist/database/base-model.js +390 -2
- package/dist/database/base-model.types.d.ts +93 -0
- package/dist/database/base-model.types.d.ts.map +1 -0
- package/dist/database/base-model.types.js +10 -0
- package/dist/database/code-generator.d.ts +1 -1
- package/dist/database/code-generator.d.ts.map +1 -1
- package/dist/database/code-generator.js +54 -2
- package/dist/database/db.d.ts +6 -21
- package/dist/database/db.d.ts.map +1 -1
- package/dist/database/db.js +129 -2
- package/dist/database/puri-subset.test-d.js +81 -0
- package/dist/database/puri-subset.types.d.ts +123 -0
- package/dist/database/puri-subset.types.d.ts.map +1 -0
- package/dist/database/puri-subset.types.js +16 -0
- package/dist/database/puri-wrapper.d.ts +13 -11
- package/dist/database/puri-wrapper.d.ts.map +1 -1
- package/dist/database/puri-wrapper.js +109 -2
- package/dist/database/puri.d.ts +41 -23
- package/dist/database/puri.d.ts.map +1 -1
- package/dist/database/puri.js +601 -2
- package/dist/database/puri.types.d.ts +25 -6
- package/dist/database/puri.types.d.ts.map +1 -1
- package/dist/database/puri.types.js +6 -2
- package/dist/database/transaction-context.d.ts +1 -1
- package/dist/database/transaction-context.d.ts.map +1 -1
- package/dist/database/transaction-context.js +14 -2
- package/dist/database/upsert-builder.d.ts +9 -3
- package/dist/database/upsert-builder.d.ts.map +1 -1
- package/dist/database/upsert-builder.js +365 -2
- package/dist/entity/entity-manager.d.ts +167 -2
- package/dist/entity/entity-manager.d.ts.map +1 -1
- package/dist/entity/entity-manager.js +130 -2
- package/dist/entity/entity.d.ts +5 -3
- package/dist/entity/entity.d.ts.map +1 -1
- package/dist/entity/entity.js +750 -2
- package/dist/exceptions/error-handler.d.ts +1 -1
- package/dist/exceptions/error-handler.d.ts.map +1 -1
- package/dist/exceptions/error-handler.js +29 -2
- package/dist/exceptions/so-exceptions.d.ts +1 -1
- package/dist/exceptions/so-exceptions.d.ts.map +1 -1
- package/dist/exceptions/so-exceptions.js +85 -2
- package/dist/file-storage/driver.d.ts +1 -1
- package/dist/file-storage/driver.d.ts.map +1 -1
- package/dist/file-storage/driver.js +79 -2
- package/dist/file-storage/file-storage.js +75 -2
- package/dist/index.d.ts +18 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +34 -2
- package/dist/migration/code-generation.d.ts +1 -1
- package/dist/migration/code-generation.d.ts.map +1 -1
- package/dist/migration/code-generation.js +614 -2
- package/dist/migration/migration-set.d.ts +2 -10
- package/dist/migration/migration-set.d.ts.map +1 -1
- package/dist/migration/migration-set.js +213 -2
- package/dist/migration/migrator.d.ts +24 -82
- package/dist/migration/migrator.d.ts.map +1 -1
- package/dist/migration/migrator.js +330 -2
- package/dist/migration/postgresql-schema-reader.d.ts +51 -0
- package/dist/migration/postgresql-schema-reader.d.ts.map +1 -0
- package/dist/migration/postgresql-schema-reader.js +245 -0
- package/dist/migration/types.d.ts +6 -38
- package/dist/migration/types.d.ts.map +1 -1
- package/dist/migration/types.js +3 -2
- package/dist/naite/messaging-types.d.ts +43 -0
- package/dist/naite/messaging-types.d.ts.map +1 -0
- package/dist/naite/messaging-types.js +7 -0
- package/dist/naite/naite-reporter.d.ts +41 -0
- package/dist/naite/naite-reporter.d.ts.map +1 -0
- package/dist/naite/naite-reporter.js +102 -0
- package/dist/naite/naite.d.ts +95 -0
- package/dist/naite/naite.d.ts.map +1 -0
- package/dist/naite/naite.js +316 -0
- package/dist/stream/index.js +3 -2
- package/dist/stream/sse.d.ts +2 -2
- package/dist/stream/sse.d.ts.map +1 -1
- package/dist/stream/sse.js +38 -2
- package/dist/syncer/api-parser.d.ts +10 -0
- package/dist/syncer/api-parser.d.ts.map +1 -0
- package/dist/syncer/api-parser.js +240 -0
- package/dist/syncer/checksum.d.ts +21 -0
- package/dist/syncer/checksum.d.ts.map +1 -0
- package/dist/syncer/checksum.js +98 -0
- package/dist/syncer/code-generator.d.ts +20 -0
- package/dist/syncer/code-generator.d.ts.map +1 -0
- package/dist/syncer/code-generator.js +161 -0
- package/dist/syncer/entity-operations.d.ts +17 -0
- package/dist/syncer/entity-operations.d.ts.map +1 -0
- package/dist/syncer/entity-operations.js +59 -0
- package/dist/syncer/file-patterns.d.ts +29 -0
- package/dist/syncer/file-patterns.d.ts.map +1 -0
- package/dist/syncer/file-patterns.js +38 -0
- package/dist/syncer/index.d.ts +6 -0
- package/dist/syncer/index.d.ts.map +1 -1
- package/dist/syncer/index.js +9 -2
- package/dist/syncer/module-loader.d.ts +35 -0
- package/dist/syncer/module-loader.d.ts.map +1 -0
- package/dist/syncer/module-loader.js +87 -0
- package/dist/syncer/syncer.d.ts +98 -106
- package/dist/syncer/syncer.d.ts.map +1 -1
- package/dist/syncer/syncer.js +422 -2
- package/dist/template/entity-converter.d.ts +14 -0
- package/dist/template/entity-converter.d.ts.map +1 -0
- package/dist/template/entity-converter.js +108 -0
- package/dist/template/helpers.d.ts +23 -0
- package/dist/template/helpers.d.ts.map +1 -0
- package/dist/template/helpers.js +64 -0
- package/dist/{templates → template/implementations}/entity.template.d.ts +3 -3
- package/dist/template/implementations/entity.template.d.ts.map +1 -0
- package/dist/template/implementations/entity.template.js +86 -0
- package/dist/{templates → template/implementations}/generated.template.d.ts +3 -4
- package/dist/template/implementations/generated.template.d.ts.map +1 -0
- package/dist/template/implementations/generated.template.js +249 -0
- package/dist/{templates → template/implementations}/generated_http.template.d.ts +3 -4
- package/dist/template/implementations/generated_http.template.d.ts.map +1 -0
- package/dist/template/implementations/generated_http.template.js +131 -0
- package/dist/{templates → template/implementations}/generated_sso.template.d.ts +4 -5
- package/dist/template/implementations/generated_sso.template.d.ts.map +1 -0
- package/dist/template/implementations/generated_sso.template.js +134 -0
- package/dist/{templates → template/implementations}/init_types.template.d.ts +3 -3
- package/dist/template/implementations/init_types.template.d.ts.map +1 -0
- package/dist/template/implementations/init_types.template.js +38 -0
- package/dist/template/implementations/model.template.d.ts +17 -0
- package/dist/template/implementations/model.template.d.ts.map +1 -0
- package/dist/template/implementations/model.template.js +181 -0
- package/dist/{templates → template/implementations}/model_test.template.d.ts +3 -3
- package/dist/template/implementations/model_test.template.d.ts.map +1 -0
- package/dist/template/implementations/model_test.template.js +35 -0
- package/dist/{templates → template/implementations}/service.template.d.ts +6 -6
- package/dist/template/implementations/service.template.d.ts.map +1 -0
- package/dist/template/implementations/service.template.js +201 -0
- package/dist/{templates → template/implementations}/view_enums_buttonset.template.d.ts +3 -3
- package/dist/template/implementations/view_enums_buttonset.template.d.ts.map +1 -0
- package/dist/template/implementations/view_enums_buttonset.template.js +31 -0
- package/dist/{templates → template/implementations}/view_enums_dropdown.template.d.ts +3 -4
- package/dist/template/implementations/view_enums_dropdown.template.d.ts.map +1 -0
- package/dist/template/implementations/view_enums_dropdown.template.js +50 -0
- package/dist/{templates → template/implementations}/view_enums_select.template.d.ts +3 -3
- package/dist/template/implementations/view_enums_select.template.d.ts.map +1 -0
- package/dist/template/implementations/view_enums_select.template.js +55 -0
- package/dist/{templates → template/implementations}/view_form.template.d.ts +5 -5
- package/dist/template/implementations/view_form.template.d.ts.map +1 -0
- package/dist/template/implementations/view_form.template.js +337 -0
- package/dist/{templates → template/implementations}/view_id_all_select.template.d.ts +3 -3
- package/dist/template/implementations/view_id_all_select.template.d.ts.map +1 -0
- package/dist/template/implementations/view_id_all_select.template.js +31 -0
- package/dist/{templates → template/implementations}/view_id_async_select.template.d.ts +3 -3
- package/dist/template/implementations/view_id_async_select.template.d.ts.map +1 -0
- package/dist/template/implementations/view_id_async_select.template.js +105 -0
- package/dist/{templates → template/implementations}/view_list.template.d.ts +5 -13
- package/dist/template/implementations/view_list.template.d.ts.map +1 -0
- package/dist/template/implementations/view_list.template.js +475 -0
- package/dist/template/implementations/view_list_columns.template.d.ts +17 -0
- package/dist/template/implementations/view_list_columns.template.d.ts.map +1 -0
- package/dist/template/implementations/view_list_columns.template.js +49 -0
- package/dist/{templates → template/implementations}/view_search_input.template.d.ts +3 -3
- package/dist/template/implementations/view_search_input.template.d.ts.map +1 -0
- package/dist/template/implementations/view_search_input.template.js +64 -0
- package/dist/template/index.d.ts +7 -0
- package/dist/template/index.d.ts.map +1 -0
- package/dist/template/index.js +8 -0
- package/dist/template/template-manager.d.ts +56 -0
- package/dist/template/template-manager.d.ts.map +1 -0
- package/dist/template/template-manager.js +125 -0
- package/dist/template/template-types.d.ts +16 -0
- package/dist/template/template-types.d.ts.map +1 -0
- package/dist/template/template-types.js +7 -0
- package/dist/template/template.d.ts +49 -0
- package/dist/template/template.d.ts.map +1 -0
- package/dist/template/template.js +60 -0
- package/dist/template/zod-converter.d.ts +51 -0
- package/dist/template/zod-converter.d.ts.map +1 -0
- package/dist/template/zod-converter.js +449 -0
- package/dist/testing/_relation-graph.d.ts +1 -1
- package/dist/testing/_relation-graph.d.ts.map +1 -1
- package/dist/testing/_relation-graph.js +89 -2
- package/dist/testing/fixture-manager.d.ts +42 -11
- package/dist/testing/fixture-manager.d.ts.map +1 -1
- package/dist/testing/fixture-manager.js +623 -2
- package/dist/types/types.d.ts +747 -143
- package/dist/types/types.d.ts.map +1 -1
- package/dist/types/types.js +546 -2
- package/dist/typings/knex.d.js +3 -2
- package/dist/utils/async-utils.d.ts +7 -0
- package/dist/utils/async-utils.d.ts.map +1 -1
- package/dist/utils/async-utils.js +57 -2
- package/dist/utils/console-util.d.ts +2 -0
- package/dist/utils/console-util.d.ts.map +1 -0
- package/dist/utils/console-util.js +6 -0
- package/dist/utils/controller.d.ts +1 -0
- package/dist/utils/controller.d.ts.map +1 -1
- package/dist/utils/controller.js +29 -2
- package/dist/utils/esm-utils.d.ts +39 -0
- package/dist/utils/esm-utils.d.ts.map +1 -0
- package/dist/utils/esm-utils.js +49 -0
- package/dist/utils/formatter.d.ts +3 -0
- package/dist/utils/formatter.d.ts.map +1 -0
- package/dist/utils/formatter.js +110 -0
- package/dist/utils/fs-utils.d.ts +1 -1
- package/dist/utils/fs-utils.d.ts.map +1 -1
- package/dist/utils/fs-utils.js +17 -2
- package/dist/utils/lodash-able.d.ts.map +1 -1
- package/dist/utils/lodash-able.js +6 -2
- package/dist/utils/model.js +22 -2
- package/dist/utils/object-utils.d.ts +44 -0
- package/dist/utils/object-utils.d.ts.map +1 -0
- package/dist/utils/object-utils.js +191 -0
- package/dist/utils/path-utils.d.ts +89 -0
- package/dist/utils/path-utils.d.ts.map +1 -0
- package/dist/utils/path-utils.js +60 -0
- package/dist/utils/process-utils.d.ts +13 -0
- package/dist/utils/process-utils.d.ts.map +1 -0
- package/dist/utils/process-utils.js +36 -0
- package/dist/utils/sql-parser.d.ts +5 -1
- package/dist/utils/sql-parser.d.ts.map +1 -1
- package/dist/utils/sql-parser.js +46 -2
- package/dist/utils/type-utils.d.ts +23 -0
- package/dist/utils/type-utils.d.ts.map +1 -0
- package/dist/utils/type-utils.js +45 -0
- package/dist/utils/utils.d.ts +10 -7
- package/dist/utils/utils.d.ts.map +1 -1
- package/dist/utils/utils.js +72 -2
- package/dist/utils/zod-error.d.ts +1 -1
- package/dist/utils/zod-error.d.ts.map +1 -1
- package/dist/utils/zod-error.js +19 -2
- package/package.json +65 -27
- package/src/ai/agents/agent.ts +87 -0
- package/src/ai/agents/index.ts +2 -0
- package/src/ai/agents/types.ts +47 -0
- package/src/ai/index.ts +1 -0
- package/src/ai/providers/rtzr/api.ts +37 -0
- package/src/ai/providers/rtzr/error.ts +34 -0
- package/src/ai/providers/rtzr/index.ts +4 -0
- package/src/ai/providers/rtzr/model.ts +201 -0
- package/src/ai/providers/rtzr/options.ts +49 -0
- package/src/ai/providers/rtzr/provider.ts +91 -0
- package/src/ai/providers/rtzr/utils.ts +127 -0
- package/src/api/base-frame.ts +4 -2
- package/src/api/caster.ts +17 -23
- package/src/api/code-converters.ts +178 -535
- package/src/api/config.ts +125 -0
- package/src/api/context.ts +7 -17
- package/src/api/decorators.ts +176 -46
- package/src/api/index.ts +2 -2
- package/src/api/sonamu.ts +190 -167
- package/src/api/validator.ts +83 -0
- package/src/bin/build-config.ts +8 -1
- package/src/bin/cli.ts +258 -124
- package/src/bin/hot-hook-register.ts +22 -0
- package/src/bin/loader-register.ts +38 -0
- package/src/database/_batch_update.ts +46 -31
- package/src/database/base-model.ts +390 -182
- package/src/database/base-model.types.ts +155 -0
- package/src/database/code-generator.ts +13 -32
- package/src/database/db.ts +40 -96
- package/src/database/puri-subset.test-d.ts +471 -0
- package/src/database/puri-subset.types.ts +195 -0
- package/src/database/puri-wrapper.ts +58 -67
- package/src/database/puri.ts +229 -148
- package/src/database/puri.types.ts +76 -30
- package/src/database/transaction-context.ts +1 -1
- package/src/database/upsert-builder.ts +262 -132
- package/src/entity/entity-manager.ts +48 -36
- package/src/entity/entity.ts +330 -248
- package/src/exceptions/error-handler.ts +3 -3
- package/src/exceptions/so-exceptions.ts +11 -11
- package/src/file-storage/driver.ts +5 -5
- package/src/file-storage/file-storage.ts +2 -2
- package/src/index.ts +18 -10
- package/src/migration/code-generation.ts +185 -172
- package/src/migration/migration-set.ts +80 -293
- package/src/migration/migrator.ts +199 -571
- package/src/migration/mysql-schema-reader.ts.txt +272 -0
- package/src/migration/postgresql-schema-reader.ts +310 -0
- package/src/migration/types.ts +6 -39
- package/src/naite/messaging-types.ts +51 -0
- package/src/naite/naite-reporter.ts +128 -0
- package/src/naite/naite.ts +415 -0
- package/src/shared/web.shared.ts.txt +20 -24
- package/src/stream/sse.ts +5 -5
- package/src/syncer/api-parser.ts +282 -0
- package/src/syncer/checksum.ts +140 -0
- package/src/syncer/code-generator.ts +198 -0
- package/src/syncer/entity-operations.ts +65 -0
- package/src/syncer/file-patterns.ts +56 -0
- package/src/syncer/index.ts +6 -0
- package/src/syncer/module-loader.ts +128 -0
- package/src/syncer/syncer.ts +389 -1453
- package/src/template/entity-converter.ts +114 -0
- package/src/template/helpers.ts +81 -0
- package/src/{templates → template/implementations}/entity.template.ts +7 -7
- package/src/{templates → template/implementations}/generated.template.ts +101 -101
- package/src/{templates → template/implementations}/generated_http.template.ts +27 -57
- package/src/template/implementations/generated_sso.template.ts +151 -0
- package/src/{templates → template/implementations}/init_types.template.ts +5 -7
- package/src/{templates → template/implementations}/model.template.ts +52 -43
- package/src/{templates → template/implementations}/model_test.template.ts +5 -5
- package/src/{templates → template/implementations}/service.template.ts +66 -82
- package/src/{templates → template/implementations}/view_enums_buttonset.template.ts +3 -3
- package/src/{templates → template/implementations}/view_enums_dropdown.template.ts +4 -20
- package/src/{templates → template/implementations}/view_enums_select.template.ts +4 -4
- package/src/{templates → template/implementations}/view_form.template.ts +40 -83
- package/src/{templates → template/implementations}/view_id_all_select.template.ts +3 -3
- package/src/{templates → template/implementations}/view_id_async_select.template.ts +10 -24
- package/src/{templates → template/implementations}/view_list.template.ts +60 -152
- package/src/{templates → template/implementations}/view_list_columns.template.ts +5 -11
- package/src/{templates → template/implementations}/view_search_input.template.ts +3 -3
- package/src/template/index.ts +6 -0
- package/src/template/template-manager.ts +166 -0
- package/src/template/template-types.ts +16 -0
- package/src/template/template.ts +105 -0
- package/src/template/zod-converter.ts +525 -0
- package/src/testing/_relation-graph.ts +18 -11
- package/src/testing/fixture-manager.ts +472 -359
- package/src/types/types.ts +553 -308
- package/src/typings/knex.d.ts +7 -9
- package/src/utils/async-utils.ts +23 -10
- package/src/utils/console-util.ts +4 -0
- package/src/utils/controller.ts +3 -0
- package/src/utils/esm-utils.ts +59 -0
- package/src/utils/formatter.ts +109 -0
- package/src/utils/fs-utils.ts +1 -1
- package/src/utils/lodash-able.ts +1 -4
- package/src/utils/object-utils.ts +217 -0
- package/src/utils/path-utils.ts +99 -0
- package/src/utils/process-utils.ts +46 -0
- package/src/utils/sql-parser.ts +23 -5
- package/src/utils/type-utils.ts +83 -0
- package/src/utils/utils.ts +66 -43
- package/src/utils/zod-error.ts +3 -4
- package/dist/api/base-frame.js.map +0 -1
- package/dist/api/caster.js.map +0 -1
- package/dist/api/code-converters.js.map +0 -1
- package/dist/api/context.js.map +0 -1
- package/dist/api/decorators.js.map +0 -1
- package/dist/api/index.js.map +0 -1
- package/dist/api/sonamu.js.map +0 -1
- package/dist/bin/build-config.js.map +0 -1
- package/dist/bin/cli-wrapper.d.ts +0 -3
- package/dist/bin/cli-wrapper.d.ts.map +0 -1
- package/dist/bin/cli-wrapper.js +0 -3
- package/dist/bin/cli-wrapper.js.map +0 -1
- package/dist/bin/cli.js.map +0 -1
- package/dist/database/_batch_update.js.map +0 -1
- package/dist/database/base-model.js.map +0 -1
- package/dist/database/code-generator.js.map +0 -1
- package/dist/database/db.js.map +0 -1
- package/dist/database/knex-plugins/knex-on-duplicate-update.d.ts +0 -2
- package/dist/database/knex-plugins/knex-on-duplicate-update.d.ts.map +0 -1
- package/dist/database/knex-plugins/knex-on-duplicate-update.js +0 -2
- package/dist/database/knex-plugins/knex-on-duplicate-update.js.map +0 -1
- package/dist/database/puri-wrapper.js.map +0 -1
- package/dist/database/puri.js.map +0 -1
- package/dist/database/puri.types.js.map +0 -1
- package/dist/database/transaction-context.js.map +0 -1
- package/dist/database/upsert-builder.js.map +0 -1
- package/dist/entity/entity-manager.js.map +0 -1
- package/dist/entity/entity-utils.d.ts +0 -61
- package/dist/entity/entity-utils.d.ts.map +0 -1
- package/dist/entity/entity-utils.js +0 -2
- package/dist/entity/entity-utils.js.map +0 -1
- package/dist/entity/entity.js.map +0 -1
- package/dist/exceptions/error-handler.js.map +0 -1
- package/dist/exceptions/so-exceptions.js.map +0 -1
- package/dist/file-storage/driver.js.map +0 -1
- package/dist/file-storage/file-storage.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/migration/code-generation.js.map +0 -1
- package/dist/migration/migration-set.js.map +0 -1
- package/dist/migration/migrator.js.map +0 -1
- package/dist/migration/types.js.map +0 -1
- package/dist/stream/index.js.map +0 -1
- package/dist/stream/sse.js.map +0 -1
- package/dist/syncer/index.js.map +0 -1
- package/dist/syncer/syncer.js.map +0 -1
- package/dist/templates/base-template.d.ts +0 -13
- package/dist/templates/base-template.d.ts.map +0 -1
- package/dist/templates/base-template.js +0 -2
- package/dist/templates/base-template.js.map +0 -1
- package/dist/templates/entity.template.d.ts.map +0 -1
- package/dist/templates/entity.template.js +0 -2
- package/dist/templates/entity.template.js.map +0 -1
- package/dist/templates/generated.template.d.ts.map +0 -1
- package/dist/templates/generated.template.js +0 -2
- package/dist/templates/generated.template.js.map +0 -1
- package/dist/templates/generated_http.template.d.ts.map +0 -1
- package/dist/templates/generated_http.template.js +0 -2
- package/dist/templates/generated_http.template.js.map +0 -1
- package/dist/templates/generated_sso.template.d.ts.map +0 -1
- package/dist/templates/generated_sso.template.js +0 -2
- package/dist/templates/generated_sso.template.js.map +0 -1
- package/dist/templates/index.d.ts +0 -2
- package/dist/templates/index.d.ts.map +0 -1
- package/dist/templates/index.js +0 -2
- package/dist/templates/index.js.map +0 -1
- package/dist/templates/init_types.template.d.ts.map +0 -1
- package/dist/templates/init_types.template.js +0 -2
- package/dist/templates/init_types.template.js.map +0 -1
- package/dist/templates/model.template.d.ts +0 -17
- package/dist/templates/model.template.d.ts.map +0 -1
- package/dist/templates/model.template.js +0 -2
- package/dist/templates/model.template.js.map +0 -1
- package/dist/templates/model_test.template.d.ts.map +0 -1
- package/dist/templates/model_test.template.js +0 -2
- package/dist/templates/model_test.template.js.map +0 -1
- package/dist/templates/service.template.d.ts.map +0 -1
- package/dist/templates/service.template.js +0 -2
- package/dist/templates/service.template.js.map +0 -1
- package/dist/templates/view_enums_buttonset.template.d.ts.map +0 -1
- package/dist/templates/view_enums_buttonset.template.js +0 -2
- package/dist/templates/view_enums_buttonset.template.js.map +0 -1
- package/dist/templates/view_enums_dropdown.template.d.ts.map +0 -1
- package/dist/templates/view_enums_dropdown.template.js +0 -2
- package/dist/templates/view_enums_dropdown.template.js.map +0 -1
- package/dist/templates/view_enums_select.template.d.ts.map +0 -1
- package/dist/templates/view_enums_select.template.js +0 -2
- package/dist/templates/view_enums_select.template.js.map +0 -1
- package/dist/templates/view_form.template.d.ts.map +0 -1
- package/dist/templates/view_form.template.js +0 -2
- package/dist/templates/view_form.template.js.map +0 -1
- package/dist/templates/view_id_all_select.template.d.ts.map +0 -1
- package/dist/templates/view_id_all_select.template.js +0 -2
- package/dist/templates/view_id_all_select.template.js.map +0 -1
- package/dist/templates/view_id_async_select.template.d.ts.map +0 -1
- package/dist/templates/view_id_async_select.template.js +0 -2
- package/dist/templates/view_id_async_select.template.js.map +0 -1
- package/dist/templates/view_list.template.d.ts.map +0 -1
- package/dist/templates/view_list.template.js +0 -2
- package/dist/templates/view_list.template.js.map +0 -1
- package/dist/templates/view_list_columns.template.d.ts +0 -17
- package/dist/templates/view_list_columns.template.d.ts.map +0 -1
- package/dist/templates/view_list_columns.template.js +0 -2
- package/dist/templates/view_list_columns.template.js.map +0 -1
- package/dist/templates/view_search_input.template.d.ts.map +0 -1
- package/dist/templates/view_search_input.template.js +0 -2
- package/dist/templates/view_search_input.template.js.map +0 -1
- package/dist/testing/_relation-graph.js.map +0 -1
- package/dist/testing/fixture-manager.js.map +0 -1
- package/dist/types/types.js.map +0 -1
- package/dist/typings/knex.d.js.map +0 -1
- package/dist/utils/async-utils.js.map +0 -1
- package/dist/utils/controller.js.map +0 -1
- package/dist/utils/fs-utils.js.map +0 -1
- package/dist/utils/lodash-able.js.map +0 -1
- package/dist/utils/model.js.map +0 -1
- package/dist/utils/sql-parser.js.map +0 -1
- package/dist/utils/utils.js.map +0 -1
- package/dist/utils/zod-error.js.map +0 -1
- package/src/bin/cli-wrapper.ts +0 -75
- package/src/database/knex-plugins/knex-on-duplicate-update.ts +0 -45
- package/src/entity/entity-utils.ts +0 -291
- package/src/templates/base-template.ts +0 -19
- package/src/templates/generated_sso.template.ts +0 -138
- package/src/templates/index.ts +0 -1
package/dist/database/puri.js
CHANGED
|
@@ -1,2 +1,601 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:true});function _export(target,all){for(var name in all)Object.defineProperty(target,name,{enumerable:true,get:Object.getOwnPropertyDescriptor(all,name).get})}_export(exports,{get JoinClauseGroup(){return JoinClauseGroup},get Puri(){return Puri},get WhereGroup(){return WhereGroup}});var _chalk=/*#__PURE__*/_interop_require_default(require("chalk"));var _assert=/*#__PURE__*/_interop_require_default(require("assert"));function _array_like_to_array(arr,len){if(len==null||len>arr.length)len=arr.length;for(var i=0,arr2=new Array(len);i<len;i++)arr2[i]=arr[i];return arr2}function _array_with_holes(arr){if(Array.isArray(arr))return arr}function _array_without_holes(arr){if(Array.isArray(arr))return _array_like_to_array(arr)}function asyncGeneratorStep(gen,resolve,reject,_next,_throw,key,arg){try{var info=gen[key](arg);var value=info.value}catch(error){reject(error);return}if(info.done){resolve(value)}else{Promise.resolve(value).then(_next,_throw)}}function _async_to_generator(fn){return function(){var self=this,args=arguments;return new Promise(function(resolve,reject){var gen=fn.apply(self,args);function _next(value){asyncGeneratorStep(gen,resolve,reject,_next,_throw,"next",value)}function _throw(err){asyncGeneratorStep(gen,resolve,reject,_next,_throw,"throw",err)}_next(undefined)})}}function _class_call_check(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function")}}function _defineProperties(target,props){for(var i=0;i<props.length;i++){var descriptor=props[i];descriptor.enumerable=descriptor.enumerable||false;descriptor.configurable=true;if("value"in descriptor)descriptor.writable=true;Object.defineProperty(target,descriptor.key,descriptor)}}function _create_class(Constructor,protoProps,staticProps){if(protoProps)_defineProperties(Constructor.prototype,protoProps);if(staticProps)_defineProperties(Constructor,staticProps);return Constructor}function _define_property(obj,key,value){if(key in obj){Object.defineProperty(obj,key,{value:value,enumerable:true,configurable:true,writable:true})}else{obj[key]=value}return obj}function _instanceof(left,right){if(right!=null&&typeof Symbol!=="undefined"&&right[Symbol.hasInstance]){return!!right[Symbol.hasInstance](left)}else{return left instanceof right}}function _interop_require_default(obj){return obj&&obj.__esModule?obj:{default:obj}}function _iterable_to_array(iter){if(typeof Symbol!=="undefined"&&iter[Symbol.iterator]!=null||iter["@@iterator"]!=null)return Array.from(iter)}function _iterable_to_array_limit(arr,i){var _i=arr==null?null:typeof Symbol!=="undefined"&&arr[Symbol.iterator]||arr["@@iterator"];if(_i==null)return;var _arr=[];var _n=true;var _d=false;var _s,_e;try{for(_i=_i.call(arr);!(_n=(_s=_i.next()).done);_n=true){_arr.push(_s.value);if(i&&_arr.length===i)break}}catch(err){_d=true;_e=err}finally{try{if(!_n&&_i["return"]!=null)_i["return"]()}finally{if(_d)throw _e}}return _arr}function _non_iterable_rest(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function _non_iterable_spread(){throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function _sliced_to_array(arr,i){return _array_with_holes(arr)||_iterable_to_array_limit(arr,i)||_unsupported_iterable_to_array(arr,i)||_non_iterable_rest()}function _to_consumable_array(arr){return _array_without_holes(arr)||_iterable_to_array(arr)||_unsupported_iterable_to_array(arr)||_non_iterable_spread()}function _type_of(obj){"@swc/helpers - typeof";return obj&&typeof Symbol!=="undefined"&&obj.constructor===Symbol?"symbol":typeof obj}function _unsupported_iterable_to_array(o,minLen){if(!o)return;if(typeof o==="string")return _array_like_to_array(o,minLen);var n=Object.prototype.toString.call(o).slice(8,-1);if(n==="Object"&&o.constructor)n=o.constructor.name;if(n==="Map"||n==="Set")return Array.from(n);if(n==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return _array_like_to_array(o,minLen)}function _ts_generator(thisArg,body){var f,y,t,_={label:0,sent:function(){if(t[0]&1)throw t[1];return t[1]},trys:[],ops:[]},g=Object.create((typeof Iterator==="function"?Iterator:Object).prototype);return g.next=verb(0),g["throw"]=verb(1),g["return"]=verb(2),typeof Symbol==="function"&&(g[Symbol.iterator]=function(){return this}),g;function verb(n){return function(v){return step([n,v])}}function step(op){if(f)throw new TypeError("Generator is already executing.");while(g&&(g=0,op[0]&&(_=0)),_)try{if(f=1,y&&(t=op[0]&2?y["return"]:op[0]?y["throw"]||((t=y["return"])&&t.call(y),0):y.next)&&!(t=t.call(y,op[1])).done)return t;if(y=0,t)op=[op[0]&2,t.value];switch(op[0]){case 0:case 1:t=op;break;case 4:_.label++;return{value:op[1],done:false};case 5:_.label++;y=op[1];op=[0];continue;case 7:op=_.ops.pop();_.trys.pop();continue;default:if(!(t=_.trys,t=t.length>0&&t[t.length-1])&&(op[0]===6||op[0]===2)){_=0;continue}if(op[0]===3&&(!t||op[1]>t[0]&&op[1]<t[3])){_.label=op[1];break}if(op[0]===6&&_.label<t[1]){_.label=t[1];t=op;break}if(t&&_.label<t[2]){_.label=t[2];_.ops.push(op);break}if(t[2])_.ops.pop();_.trys.pop();continue}op=body.call(thisArg,_)}catch(e){op=[6,e];y=0}finally{f=t=0}if(op[0]&5)throw op[1];return{value:op[0]?op[1]:void 0,done:true}}}var Puri=/*#__PURE__*/function(){"use strict";function Puri(knex,tableNameOrSpec){_class_call_check(this,Puri);_define_property(this,"knex",void 0);_define_property(this,"knexQuery",void 0);this.knex=knex;if(typeof tableNameOrSpec==="string"){this.knexQuery=this.knex(tableNameOrSpec).from(tableNameOrSpec)}else if((typeof tableNameOrSpec==="undefined"?"undefined":_type_of(tableNameOrSpec))==="object"){var entries=Object.entries(tableNameOrSpec);if(entries.length!==1){throw new Error("Table spec must have exactly one entry")}(0,_assert.default)(entries[0]);var _entries_=_sliced_to_array(entries[0],2),alias=_entries_[0],spec=_entries_[1];if(typeof spec==="string"){this.knexQuery=this.knex(spec).from(_define_property({},alias,spec))}else if(_instanceof(spec,Puri)){var subqueryBuilder=spec.raw();this.knexQuery=this.knex.from(subqueryBuilder.as(alias))}else{throw new Error("Invalid table specification")}}else{throw new Error("Invalid table specification")}}_create_class(Puri,[{key:"select",value:function select(selectObj){var selectClauses=[];var _iteratorNormalCompletion=true,_didIteratorError=false,_iteratorError=undefined;try{for(var _iterator=Object.entries(selectObj)[Symbol.iterator](),_step;!(_iteratorNormalCompletion=(_step=_iterator.next()).done);_iteratorNormalCompletion=true){var _step_value=_sliced_to_array(_step.value,2),alias=_step_value[0],columnOrFunction=_step_value[1];if((typeof columnOrFunction==="undefined"?"undefined":_type_of(columnOrFunction))==="object"&&columnOrFunction._type==="sql_expression"){selectClauses.push(this.knex.raw("".concat(columnOrFunction._sql," as ").concat(alias)))}else{var columnPath=columnOrFunction;if(alias===columnPath){selectClauses.push(columnPath)}else{selectClauses.push("".concat(columnPath," as ").concat(alias))}}}}catch(err){_didIteratorError=true;_iteratorError=err}finally{try{if(!_iteratorNormalCompletion&&_iterator.return!=null){_iterator.return()}}finally{if(_didIteratorError){throw _iteratorError}}}this.knexQuery.select(selectClauses);return this}},{key:"selectAll",value:function selectAll(){this.knexQuery.select("*");return this}},{key:"join",value:function join(tableNameOrSpec){for(var _len=arguments.length,args=new Array(_len>1?_len-1:0),_key=1;_key<_len;_key++){args[_key-1]=arguments[_key]}return this.__commonJoin.apply(this,["join",tableNameOrSpec].concat(_to_consumable_array(args)))}},{key:"leftJoin",value:function leftJoin(tableNameOrSpec){for(var _len=arguments.length,args=new Array(_len>1?_len-1:0),_key=1;_key<_len;_key++){args[_key-1]=arguments[_key]}return this.__commonJoin.apply(this,["leftJoin",tableNameOrSpec].concat(_to_consumable_array(args)))}},{key:"__commonJoin",value:function __commonJoin(joinType,tableNameOrSpec){for(var _len=arguments.length,args=new Array(_len>2?_len-2:0),_key=2;_key<_len;_key++){args[_key-2]=arguments[_key]}if(typeof tableNameOrSpec==="string"){var tableName=tableNameOrSpec;if(args.length===1&&typeof args[0]==="function"){var callback=args[0];this.knexQuery[joinType](tableName,function(joinClause){callback(new JoinClauseGroup(joinClause))})}else{var _args=_sliced_to_array(args,2),left=_args[0],right=_args[1];this.knexQuery[joinType](tableName,left,right)}}else if((typeof tableNameOrSpec==="undefined"?"undefined":_type_of(tableNameOrSpec))==="object"){var entries=Object.entries(tableNameOrSpec);if(entries.length!==1){throw new Error("Table spec must have exactly one entry")}(0,_assert.default)(entries[0]);var _entries=_sliced_to_array(entries,1),_entries_=_sliced_to_array(_entries[0],2),alias=_entries_[0],spec=_entries_[1];if(typeof spec==="string"){if(args.length===1&&typeof args[0]==="function"){var callback1=args[0];this.knexQuery[joinType](_define_property({},alias,spec),function(joinClause){callback1(new JoinClauseGroup(joinClause))})}else{var _args1=_sliced_to_array(args,2),left1=_args1[0],right1=_args1[1];this.knexQuery[joinType](_define_property({},alias,spec),left1,right1)}}else if(_instanceof(spec,Puri)){if(args.length===1&&typeof args[0]==="function"){var callback2=args[0];this.knexQuery[joinType](spec.raw().as(alias),function(joinClause){callback2(new JoinClauseGroup(joinClause))})}else{var _args2=_sliced_to_array(args,2),left2=_args2[0],right2=_args2[1];this.knexQuery[joinType](spec.raw().as(alias),left2,right2)}}else{throw new Error("Invalid table specification")}}else{throw new Error("Invalid arguments")}return this}},{key:"where",value:function where(columnOrConditions,operatorOrValue,value){if((typeof columnOrConditions==="undefined"?"undefined":_type_of(columnOrConditions))==="object"){this.knexQuery.where(columnOrConditions)}else if(arguments.length===2){if(operatorOrValue===null){this.knexQuery.whereNull(columnOrConditions);return this}this.knexQuery.where(columnOrConditions,operatorOrValue)}else if(arguments.length===3){if(value===null){if(operatorOrValue==="!="){this.knexQuery.whereNotNull(columnOrConditions);return this}else if(operatorOrValue==="="){this.knexQuery.whereNull(columnOrConditions);return this}}this.knexQuery.where(columnOrConditions,operatorOrValue,value)}else{this.knexQuery.where(columnOrConditions)}return this}},{key:"whereIn",value:function whereIn(column,values){this.knexQuery.whereIn(column,values);return this}},{key:"whereNotIn",value:function whereNotIn(column,values){this.knexQuery.whereIn(column,values);return this}},{key:"whereMatch",value:function whereMatch(column,value){this.knexQuery.whereRaw("MATCH (".concat(String(column),") AGAINST (?)"),[value]);return this}},{key:"whereGroup",value:function whereGroup(callback){this.knexQuery.where(function(builder){var group=new WhereGroup(builder);callback(group)});return this}},{key:"orWhereGroup",value:function orWhereGroup(callback){this.knexQuery.orWhere(function(builder){var group=new WhereGroup(builder);callback(group)});return this}},{key:"orderBy",value:function orderBy(column){var direction=arguments.length>1&&arguments[1]!==void 0?arguments[1]:"asc";this.knexQuery.orderBy(column,direction);return this}},{key:"limit",value:function limit(count){this.knexQuery.limit(count);return this}},{key:"offset",value:function offset(count){this.knexQuery.offset(count);return this}},{key:"groupBy",value:function groupBy(){for(var _len=arguments.length,columns=new Array(_len),_key=0;_key<_len;_key++){columns[_key]=arguments[_key]}var _this_knexQuery;(_this_knexQuery=this.knexQuery).groupBy.apply(_this_knexQuery,_to_consumable_array(columns));return this}},{key:"having",value:function having(){for(var _len=arguments.length,conditions=new Array(_len),_key=0;_key<_len;_key++){conditions[_key]=arguments[_key]}if(conditions.length===1){this.knexQuery.having(conditions[0])}else if(conditions.length===3){this.knexQuery.having(conditions[0],conditions[1],conditions[2])}else{throw new Error("Invalid having arguments")}return this}},{key:"then",value:function then(onfulfilled,onrejected){return this.knexQuery.then(onfulfilled,onrejected)}},{key:"catch",value:function _catch(onrejected){return this.knexQuery.catch(onrejected)}},{key:"finally",value:function _finally(onfinally){return this.knexQuery.finally(onfinally)}},{key:"first",value:function first(){return _async_to_generator(function(){return _ts_generator(this,function(_state){return[2,this.knexQuery.first()]})}).call(this)}},{key:"firstOrFail",value:function firstOrFail(){return _async_to_generator(function(){var result;return _ts_generator(this,function(_state){switch(_state.label){case 0:return[4,this.knexQuery.first()];case 1:result=_state.sent();if(!result){throw new Error("No results found")}return[2,result]}})}).call(this)}},{key:"at",value:function at(index){return _async_to_generator(function(){var results;return _ts_generator(this,function(_state){switch(_state.label){case 0:return[4,this];case 1:results=_state.sent();return[2,results[index]]}})}).call(this)}},{key:"assertAt",value:function assertAt(index){return _async_to_generator(function(){var results,result;return _ts_generator(this,function(_state){switch(_state.label){case 0:return[4,this];case 1:results=_state.sent();result=results[index];if(result===undefined){throw new Error("No result found at index ".concat(index))}return[2,result]}})}).call(this)}},{key:"pluck",value:function pluck(column){return _async_to_generator(function(){return _ts_generator(this,function(_state){return[2,this.knexQuery.pluck(column)]})}).call(this)}},{key:"insert",value:function insert(data){this.knexQuery.insert(data);return this}},{key:"update",value:function update(data){this.knexQuery.update(data);return this}},{key:"increment",value:function increment(column,value){if(value<=0){throw new Error("Increment value must be greater than 0")}this.knexQuery.increment(column,value);return this}},{key:"decrement",value:function decrement(column,value){if(value<=0){throw new Error("Decrement value must be greater than 0")}this.knexQuery.decrement(column,value);return this}},{key:"delete",value:function _delete(){this.knexQuery.delete();return this}},{key:"toQuery",value:function toQuery(){return this.knexQuery.toQuery()}},{key:"debug",value:function debug(){console.log("".concat(_chalk.default.cyan("[Puri Debug]")," ").concat(_chalk.default.yellow(this.toQuery())));return this}},{key:"formatSQL",value:function formatSQL(unformatted){var keywords=["SELECT","FROM","WHERE","INSERT","INTO","VALUES","UPDATE","DELETE","CREATE","TABLE","ALTER","DROP","JOIN","ON","INNER","LEFT","RIGHT","FULL","OUTER","GROUP","BY","ORDER","HAVING","DISTINCT","LIMIT","OFFSET","AS","AND","OR","NOT","IN","LIKE","IS","NULL","CASE","WHEN","THEN","ELSE","END","UNION","ALL","EXISTS","BETWEEN"];var formatted=unformatted;keywords.forEach(function(keyword){var regex=new RegExp("\\b".concat(keyword,"\\b"),"gi");formatted=formatted.replace(regex,keyword.toUpperCase())});var majorClauses=["SELECT","FROM","WHERE","GROUP BY","ORDER BY","HAVING","LIMIT","UNION"];majorClauses.forEach(function(clause){var regex=new RegExp("\\s+(".concat(clause,")\\s+"),"gi");formatted=formatted.replace(regex,"\n".concat(clause.toUpperCase()," "))});formatted=formatted.replace(/\s+((?:INNER|LEFT|RIGHT|FULL OUTER)\s+)?JOIN\s+/gi,"\n$1JOIN ");formatted=formatted.replace(/\s+(AND|OR)\s+/gi,"\n $1 ");var lines=formatted.split("\n");var indentedLines=[];var indentLevel=0;var _iteratorNormalCompletion=true,_didIteratorError=false,_iteratorError=undefined;try{for(var _iterator=lines[Symbol.iterator](),_step;!(_iteratorNormalCompletion=(_step=_iterator.next()).done);_iteratorNormalCompletion=true){var line=_step.value;var trimmedLine=line.trim();if(!trimmedLine)continue;var closingParens=(trimmedLine.match(/\)/g)||[]).length;var openingParens=(trimmedLine.match(/\(/g)||[]).length;if(closingParens>0&&openingParens===0){indentLevel=Math.max(0,indentLevel-closingParens)}var indent=" ".repeat(indentLevel);indentedLines.push(indent+trimmedLine);if(openingParens>closingParens){indentLevel+=openingParens-closingParens}}}catch(err){_didIteratorError=true;_iteratorError=err}finally{try{if(!_iteratorNormalCompletion&&_iterator.return!=null){_iterator.return()}}finally{if(_didIteratorError){throw _iteratorError}}}return indentedLines.join("\n").trim()}},{key:"raw",value:function raw(){return this.knexQuery}}],[{key:"count",value:function count(){var column=arguments.length>0&&arguments[0]!==void 0?arguments[0]:"*";return{_type:"sql_expression",_return:"number",_sql:"COUNT(".concat(column,")")}}},{key:"sum",value:function sum(column){return{_type:"sql_expression",_return:"number",_sql:"SUM(".concat(column,")")}}},{key:"avg",value:function avg(column){return{_type:"sql_expression",_return:"number",_sql:"AVG(".concat(column,")")}}},{key:"max",value:function max(column){return{_type:"sql_expression",_return:"number",_sql:"MAX(".concat(column,")")}}},{key:"min",value:function min(column){return{_type:"sql_expression",_return:"number",_sql:"MIN(".concat(column,")")}}},{key:"concat",value:function concat(){for(var _len=arguments.length,args=new Array(_len),_key=0;_key<_len;_key++){args[_key]=arguments[_key]}return{_type:"sql_expression",_return:"string",_sql:"CONCAT(".concat(args.join(", "),")")}}},{key:"upper",value:function upper(column){return{_type:"sql_expression",_return:"string",_sql:"UPPER(".concat(column,")")}}},{key:"lower",value:function lower(column){return{_type:"sql_expression",_return:"string",_sql:"LOWER(".concat(column,")")}}},{key:"rawString",value:function rawString(sql){return{_type:"sql_expression",_return:"string",_sql:sql}}},{key:"rawNumber",value:function rawNumber(sql){return{_type:"sql_expression",_return:"number",_sql:sql}}},{key:"rawBoolean",value:function rawBoolean(sql){return{_type:"sql_expression",_return:"boolean",_sql:sql}}},{key:"rawDate",value:function rawDate(sql){return{_type:"sql_expression",_return:"date",_sql:sql}}}]);return Puri}();var WhereGroup=/*#__PURE__*/function(){"use strict";function WhereGroup(builder){_class_call_check(this,WhereGroup);_define_property(this,"builder",void 0);this.builder=builder}_create_class(WhereGroup,[{key:"where",value:function where(){for(var _len=arguments.length,args=new Array(_len),_key=0;_key<_len;_key++){args[_key]=arguments[_key]}var _this_builder;(_this_builder=this.builder).where.apply(_this_builder,[args[0]].concat(_to_consumable_array(args.slice(1))));return this}},{key:"orWhere",value:function orWhere(){for(var _len=arguments.length,args=new Array(_len),_key=0;_key<_len;_key++){args[_key]=arguments[_key]}var _this_builder;(_this_builder=this.builder).orWhere.apply(_this_builder,[args[0]].concat(_to_consumable_array(args.slice(1))));return this}},{key:"whereGroup",value:function whereGroup(callback){this.builder.where(function(subBuilder){var subGroup=new WhereGroup(subBuilder);callback(subGroup)});return this}},{key:"orWhereGroup",value:function orWhereGroup(callback){this.builder.orWhere(function(subBuilder){var subGroup=new WhereGroup(subBuilder);callback(subGroup)});return this}}]);return WhereGroup}();var JoinClauseGroup=/*#__PURE__*/function(){"use strict";function JoinClauseGroup(callback){_class_call_check(this,JoinClauseGroup);_define_property(this,"callback",void 0);this.callback=callback}_create_class(JoinClauseGroup,[{key:"on",value:function on(){for(var _len=arguments.length,args=new Array(_len),_key=0;_key<_len;_key++){args[_key]=arguments[_key]}var _this_callback;(_this_callback=this.callback).on.apply(_this_callback,_to_consumable_array(args));return this}},{key:"orOn",value:function orOn(){for(var _len=arguments.length,args=new Array(_len),_key=0;_key<_len;_key++){args[_key]=arguments[_key]}var _this_callback;(_this_callback=this.callback).orOn.apply(_this_callback,_to_consumable_array(args));return this}}]);return JoinClauseGroup}();
|
|
2
|
-
|
|
1
|
+
/** biome-ignore-all lint/suspicious/noThenProperty: Puri는 thenable 인터페이스를 구현하고 있습니다. */ /** biome-ignore-all lint/suspicious/noExplicitAny: Puri는 다양한 타입을 사용하고 있습니다. */ import assert from "assert";
|
|
2
|
+
import chalk from "chalk";
|
|
3
|
+
import { Naite } from "../naite/naite.js";
|
|
4
|
+
export class Puri {
|
|
5
|
+
knex;
|
|
6
|
+
knexQuery;
|
|
7
|
+
constructor(knex, tableNameOrSpec){
|
|
8
|
+
this.knex = knex;
|
|
9
|
+
if (typeof tableNameOrSpec === "string") {
|
|
10
|
+
// Case: new Puri(knex, "users")
|
|
11
|
+
this.knexQuery = this.knex(tableNameOrSpec).from(tableNameOrSpec);
|
|
12
|
+
} else if (typeof tableNameOrSpec === "object") {
|
|
13
|
+
const entries = Object.entries(tableNameOrSpec);
|
|
14
|
+
if (entries.length !== 1) {
|
|
15
|
+
throw new Error("Table spec must have exactly one entry");
|
|
16
|
+
}
|
|
17
|
+
assert(entries[0]);
|
|
18
|
+
const [alias, spec] = entries[0];
|
|
19
|
+
if (typeof spec === "string") {
|
|
20
|
+
this.knexQuery = this.knex(spec).from({
|
|
21
|
+
[alias]: spec
|
|
22
|
+
});
|
|
23
|
+
} else if (spec instanceof Puri) {
|
|
24
|
+
const subqueryBuilder = spec.raw();
|
|
25
|
+
this.knexQuery = this.knex.from(subqueryBuilder.as(alias));
|
|
26
|
+
} else {
|
|
27
|
+
throw new Error("Invalid table specification");
|
|
28
|
+
}
|
|
29
|
+
} else {
|
|
30
|
+
throw new Error("Invalid table specification");
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
// Static SQL helper functions for SELECT
|
|
34
|
+
static count(column = "*") {
|
|
35
|
+
return {
|
|
36
|
+
_type: "sql_expression",
|
|
37
|
+
_return: "number",
|
|
38
|
+
_sql: `COUNT(${column})::integer`
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
static sum(column) {
|
|
42
|
+
return {
|
|
43
|
+
_type: "sql_expression",
|
|
44
|
+
_return: "number",
|
|
45
|
+
_sql: `SUM(${column})`
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
static avg(column) {
|
|
49
|
+
return {
|
|
50
|
+
_type: "sql_expression",
|
|
51
|
+
_return: "number",
|
|
52
|
+
_sql: `AVG(${column})`
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
static max(column) {
|
|
56
|
+
return {
|
|
57
|
+
_type: "sql_expression",
|
|
58
|
+
_return: "number",
|
|
59
|
+
_sql: `MAX(${column})`
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
static min(column) {
|
|
63
|
+
return {
|
|
64
|
+
_type: "sql_expression",
|
|
65
|
+
_return: "number",
|
|
66
|
+
_sql: `MIN(${column})`
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
static concat(...args) {
|
|
70
|
+
return {
|
|
71
|
+
_type: "sql_expression",
|
|
72
|
+
_return: "string",
|
|
73
|
+
_sql: `CONCAT(${args.join(", ")})`
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
static upper(column) {
|
|
77
|
+
return {
|
|
78
|
+
_type: "sql_expression",
|
|
79
|
+
_return: "string",
|
|
80
|
+
_sql: `UPPER(${column})`
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
static lower(column) {
|
|
84
|
+
return {
|
|
85
|
+
_type: "sql_expression",
|
|
86
|
+
_return: "string",
|
|
87
|
+
_sql: `LOWER(${column})`
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
// Raw functions for SELECT
|
|
91
|
+
static rawString(sql) {
|
|
92
|
+
return {
|
|
93
|
+
_type: "sql_expression",
|
|
94
|
+
_return: "string",
|
|
95
|
+
_sql: sql
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
static rawNumber(sql) {
|
|
99
|
+
return {
|
|
100
|
+
_type: "sql_expression",
|
|
101
|
+
_return: "number",
|
|
102
|
+
_sql: sql
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
static rawBoolean(sql) {
|
|
106
|
+
return {
|
|
107
|
+
_type: "sql_expression",
|
|
108
|
+
_return: "boolean",
|
|
109
|
+
_sql: sql
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
static rawDate(sql) {
|
|
113
|
+
return {
|
|
114
|
+
_type: "sql_expression",
|
|
115
|
+
_return: "date",
|
|
116
|
+
_sql: sql
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
// SELECT (overwrite)
|
|
120
|
+
select(selectObj) {
|
|
121
|
+
const selectClauses = [];
|
|
122
|
+
for (const [alias, columnOrFunction] of Object.entries(selectObj)){
|
|
123
|
+
if (typeof columnOrFunction === "object" && columnOrFunction._type === "sql_expression") {
|
|
124
|
+
// SQL 함수인 경우
|
|
125
|
+
selectClauses.push(this.knex.raw(`${columnOrFunction._sql} as ${alias}`));
|
|
126
|
+
} else {
|
|
127
|
+
// 일반 컬럼인 경우
|
|
128
|
+
const columnPath = columnOrFunction;
|
|
129
|
+
if (alias === columnPath) {
|
|
130
|
+
// alias와 컬럼명이 같으면 alias 생략
|
|
131
|
+
selectClauses.push(columnPath);
|
|
132
|
+
} else {
|
|
133
|
+
// alias 지정
|
|
134
|
+
selectClauses.push(`${columnPath} as ${alias}`);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
this.knexQuery.select(selectClauses);
|
|
139
|
+
return this;
|
|
140
|
+
}
|
|
141
|
+
// SELECT (select는 overwrite, appendSelect는 append)
|
|
142
|
+
appendSelect(selectObj) {
|
|
143
|
+
return this.select(selectObj);
|
|
144
|
+
}
|
|
145
|
+
// SELECT *
|
|
146
|
+
selectAll() {
|
|
147
|
+
this.knexQuery.select("*");
|
|
148
|
+
return this;
|
|
149
|
+
}
|
|
150
|
+
// CLEAR
|
|
151
|
+
clear(statement) {
|
|
152
|
+
this.knexQuery.clear(statement);
|
|
153
|
+
return this;
|
|
154
|
+
}
|
|
155
|
+
// knex에 없어서 직접 구현함
|
|
156
|
+
clearJoin(alias) {
|
|
157
|
+
this.knexQuery._statements = this.knexQuery._statements.filter((s)=>{
|
|
158
|
+
if ("joinType" in s) {
|
|
159
|
+
const [_alias, _table] = Object.entries(s.table)[0];
|
|
160
|
+
return _alias !== alias;
|
|
161
|
+
} else {
|
|
162
|
+
return true;
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
return this;
|
|
166
|
+
}
|
|
167
|
+
// JOIN 실제 구현
|
|
168
|
+
join(tableNameOrSpec, ...args) {
|
|
169
|
+
return this.__commonJoin("join", tableNameOrSpec, ...args);
|
|
170
|
+
}
|
|
171
|
+
// LEFT JOIN 실제 구현
|
|
172
|
+
leftJoin(tableNameOrSpec, ...args) {
|
|
173
|
+
return this.__commonJoin("leftJoin", tableNameOrSpec, ...args);
|
|
174
|
+
}
|
|
175
|
+
__commonJoin(joinType, tableNameOrSpec, ...args) {
|
|
176
|
+
if (typeof tableNameOrSpec === "string") {
|
|
177
|
+
// Case 1: join("posts", ...)
|
|
178
|
+
const tableName = tableNameOrSpec;
|
|
179
|
+
if (args.length === 1 && typeof args[0] === "function") {
|
|
180
|
+
// join("posts", callback)
|
|
181
|
+
const callback = args[0];
|
|
182
|
+
this.knexQuery[joinType](tableName, (joinClause)=>{
|
|
183
|
+
callback(new JoinClauseGroup(joinClause));
|
|
184
|
+
});
|
|
185
|
+
} else {
|
|
186
|
+
// join("posts", left, right)
|
|
187
|
+
const [left, right] = args;
|
|
188
|
+
this.knexQuery[joinType](tableName, left, right);
|
|
189
|
+
}
|
|
190
|
+
} else if (typeof tableNameOrSpec === "object") {
|
|
191
|
+
// Case 2: join({ alias: "table" }, ...) or join({ alias: subquery }, ...)
|
|
192
|
+
const entries = Object.entries(tableNameOrSpec);
|
|
193
|
+
if (entries.length !== 1) {
|
|
194
|
+
throw new Error("Table spec must have exactly one entry");
|
|
195
|
+
}
|
|
196
|
+
assert(entries[0]);
|
|
197
|
+
const [[alias, spec]] = entries;
|
|
198
|
+
if (typeof spec === "string") {
|
|
199
|
+
// 테이블: join({ p: "posts" }, ...)
|
|
200
|
+
if (args.length === 1 && typeof args[0] === "function") {
|
|
201
|
+
// Callback
|
|
202
|
+
const callback = args[0];
|
|
203
|
+
this.knexQuery[joinType]({
|
|
204
|
+
[alias]: spec
|
|
205
|
+
}, (joinClause)=>{
|
|
206
|
+
callback(new JoinClauseGroup(joinClause));
|
|
207
|
+
});
|
|
208
|
+
} else {
|
|
209
|
+
// Simple
|
|
210
|
+
const [left, right] = args;
|
|
211
|
+
this.knexQuery[joinType]({
|
|
212
|
+
[alias]: spec
|
|
213
|
+
}, left, right);
|
|
214
|
+
}
|
|
215
|
+
} else if (spec instanceof Puri) {
|
|
216
|
+
// 서브쿼리: join({ sq: subquery }, ...)
|
|
217
|
+
if (args.length === 1 && typeof args[0] === "function") {
|
|
218
|
+
// Callback
|
|
219
|
+
const callback = args[0];
|
|
220
|
+
this.knexQuery[joinType](spec.raw().as(alias), (joinClause)=>{
|
|
221
|
+
callback(new JoinClauseGroup(joinClause));
|
|
222
|
+
});
|
|
223
|
+
} else {
|
|
224
|
+
// Simple
|
|
225
|
+
const [left, right] = args;
|
|
226
|
+
this.knexQuery[joinType](spec.raw().as(alias), left, right);
|
|
227
|
+
}
|
|
228
|
+
} else {
|
|
229
|
+
throw new Error("Invalid table specification");
|
|
230
|
+
}
|
|
231
|
+
} else {
|
|
232
|
+
throw new Error("Invalid arguments");
|
|
233
|
+
}
|
|
234
|
+
return this;
|
|
235
|
+
}
|
|
236
|
+
// WHERE: 컬럼 - 사용: .where("u.id", "like", "%test%")
|
|
237
|
+
where(...args) {
|
|
238
|
+
const [columnOrConditions, operatorOrValue, value] = args;
|
|
239
|
+
if (typeof columnOrConditions === "object") {
|
|
240
|
+
this.knexQuery.where(columnOrConditions);
|
|
241
|
+
} else if (typeof value === "undefined") {
|
|
242
|
+
if (operatorOrValue === null) {
|
|
243
|
+
this.knexQuery.whereNull(columnOrConditions);
|
|
244
|
+
return this;
|
|
245
|
+
}
|
|
246
|
+
this.knexQuery.where(columnOrConditions, operatorOrValue);
|
|
247
|
+
} else if (typeof value !== "undefined") {
|
|
248
|
+
if (value === null) {
|
|
249
|
+
if (operatorOrValue === "!=") {
|
|
250
|
+
this.knexQuery.whereNotNull(columnOrConditions);
|
|
251
|
+
return this;
|
|
252
|
+
} else if (operatorOrValue === "=") {
|
|
253
|
+
this.knexQuery.whereNull(columnOrConditions);
|
|
254
|
+
return this;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
this.knexQuery.where(columnOrConditions, operatorOrValue, value);
|
|
258
|
+
} else {
|
|
259
|
+
this.knexQuery.where(columnOrConditions);
|
|
260
|
+
}
|
|
261
|
+
return this;
|
|
262
|
+
}
|
|
263
|
+
// WHERE IN
|
|
264
|
+
whereIn(column, values) {
|
|
265
|
+
this.knexQuery.whereIn(column, values);
|
|
266
|
+
return this;
|
|
267
|
+
}
|
|
268
|
+
// WHERE NOT IN
|
|
269
|
+
whereNotIn(column, values) {
|
|
270
|
+
this.knexQuery.whereNotIn(column, values);
|
|
271
|
+
return this;
|
|
272
|
+
}
|
|
273
|
+
// WHERE MATCH
|
|
274
|
+
whereMatch(column, value) {
|
|
275
|
+
this.knexQuery.whereRaw(`MATCH (${String(column)}) AGAINST (?)`, [
|
|
276
|
+
value
|
|
277
|
+
]);
|
|
278
|
+
return this;
|
|
279
|
+
}
|
|
280
|
+
// WHERE 괄호 그룹핑
|
|
281
|
+
whereGroup(callback) {
|
|
282
|
+
this.knexQuery.where((builder)=>{
|
|
283
|
+
const group = new WhereGroup(builder);
|
|
284
|
+
callback(group);
|
|
285
|
+
});
|
|
286
|
+
return this;
|
|
287
|
+
}
|
|
288
|
+
orWhereGroup(callback) {
|
|
289
|
+
this.knexQuery.orWhere((builder)=>{
|
|
290
|
+
const group = new WhereGroup(builder);
|
|
291
|
+
callback(group);
|
|
292
|
+
});
|
|
293
|
+
return this;
|
|
294
|
+
}
|
|
295
|
+
orderBy(column, direction = "asc") {
|
|
296
|
+
this.knexQuery.orderBy(column, direction);
|
|
297
|
+
return this;
|
|
298
|
+
}
|
|
299
|
+
// 기본 쿼리 메서드들
|
|
300
|
+
limit(count) {
|
|
301
|
+
this.knexQuery.limit(count);
|
|
302
|
+
return this;
|
|
303
|
+
}
|
|
304
|
+
offset(count) {
|
|
305
|
+
this.knexQuery.offset(count);
|
|
306
|
+
return this;
|
|
307
|
+
}
|
|
308
|
+
groupBy(...columns) {
|
|
309
|
+
this.knexQuery.groupBy(...columns);
|
|
310
|
+
return this;
|
|
311
|
+
}
|
|
312
|
+
// HAVING 구현
|
|
313
|
+
having(...conditions) {
|
|
314
|
+
if (conditions.length === 1) {
|
|
315
|
+
// having("COUNT(*) > 10")
|
|
316
|
+
this.knexQuery.having(this.knex.raw(conditions[0]));
|
|
317
|
+
} else if (conditions.length === 3) {
|
|
318
|
+
// having("count", ">", 10)
|
|
319
|
+
this.knexQuery.having(this.knex.raw(conditions[0]), conditions[1], this.knex.raw(conditions[2]));
|
|
320
|
+
} else {
|
|
321
|
+
throw new Error("Invalid having arguments");
|
|
322
|
+
}
|
|
323
|
+
return this;
|
|
324
|
+
}
|
|
325
|
+
// 실행 메서드들 - thenable 구현
|
|
326
|
+
then(onfulfilled, onrejected) {
|
|
327
|
+
Naite.t("puri:executed-query", this.toQuery());
|
|
328
|
+
return this.knexQuery.then(onfulfilled, onrejected);
|
|
329
|
+
}
|
|
330
|
+
catch(onrejected) {
|
|
331
|
+
return this.knexQuery.catch(onrejected);
|
|
332
|
+
}
|
|
333
|
+
finally(onfinally) {
|
|
334
|
+
return this.knexQuery.finally(onfinally);
|
|
335
|
+
}
|
|
336
|
+
// 하나만 쿼리
|
|
337
|
+
first() {
|
|
338
|
+
this.knexQuery.first();
|
|
339
|
+
return new ResolvedPuri(this.knexQuery, this.knex);
|
|
340
|
+
}
|
|
341
|
+
// 쿼리한 레코드에서 특정 컬럼만 추출한 배열 리턴
|
|
342
|
+
pluck(column) {
|
|
343
|
+
this.knexQuery.pluck(column);
|
|
344
|
+
return new ResolvedPuri(this.knexQuery, this.knex);
|
|
345
|
+
}
|
|
346
|
+
// INSERT
|
|
347
|
+
insert(data) {
|
|
348
|
+
this.knexQuery.insert(data);
|
|
349
|
+
return new ResolvedPuri(this.knexQuery, this.knex);
|
|
350
|
+
}
|
|
351
|
+
// UPDATE
|
|
352
|
+
update(data) {
|
|
353
|
+
this.knexQuery.update(data);
|
|
354
|
+
return new ResolvedPuri(this.knexQuery, this.knex);
|
|
355
|
+
}
|
|
356
|
+
// Increment
|
|
357
|
+
increment(column, value) {
|
|
358
|
+
if (value <= 0) {
|
|
359
|
+
throw new Error("Increment value must be greater than 0");
|
|
360
|
+
}
|
|
361
|
+
this.knexQuery.increment(column, value);
|
|
362
|
+
return new ResolvedPuri(this.knexQuery, this.knex);
|
|
363
|
+
}
|
|
364
|
+
// Decrement
|
|
365
|
+
decrement(column, value) {
|
|
366
|
+
if (value <= 0) {
|
|
367
|
+
throw new Error("Decrement value must be greater than 0");
|
|
368
|
+
}
|
|
369
|
+
this.knexQuery.decrement(column, value);
|
|
370
|
+
return new ResolvedPuri(this.knexQuery, this.knex);
|
|
371
|
+
}
|
|
372
|
+
// DELETE
|
|
373
|
+
delete() {
|
|
374
|
+
this.knexQuery.delete();
|
|
375
|
+
return new ResolvedPuri(this.knexQuery, this.knex);
|
|
376
|
+
}
|
|
377
|
+
// 확인 쿼리 리턴
|
|
378
|
+
toQuery() {
|
|
379
|
+
return this.knexQuery.toQuery();
|
|
380
|
+
}
|
|
381
|
+
// 쿼리 디버깅 로그 출력
|
|
382
|
+
debug() {
|
|
383
|
+
console.log(`${chalk.cyan("[Puri Debug]")} ${chalk.yellow(this.toQuery())}`);
|
|
384
|
+
return this;
|
|
385
|
+
}
|
|
386
|
+
clone() {
|
|
387
|
+
// 'dual'은 더미 테이블이며, 바로 아래 줄에서 knexQuery가 덮어씌워집니다.
|
|
388
|
+
const newPuri = new Puri(this.knex, "dual");
|
|
389
|
+
newPuri.knexQuery = this.knexQuery.clone();
|
|
390
|
+
return newPuri;
|
|
391
|
+
}
|
|
392
|
+
formatSQL(unformatted) {
|
|
393
|
+
// SQL 예약어 목록
|
|
394
|
+
const keywords = [
|
|
395
|
+
"SELECT",
|
|
396
|
+
"FROM",
|
|
397
|
+
"WHERE",
|
|
398
|
+
"INSERT",
|
|
399
|
+
"INTO",
|
|
400
|
+
"VALUES",
|
|
401
|
+
"UPDATE",
|
|
402
|
+
"DELETE",
|
|
403
|
+
"CREATE",
|
|
404
|
+
"TABLE",
|
|
405
|
+
"ALTER",
|
|
406
|
+
"DROP",
|
|
407
|
+
"JOIN",
|
|
408
|
+
"ON",
|
|
409
|
+
"INNER",
|
|
410
|
+
"LEFT",
|
|
411
|
+
"RIGHT",
|
|
412
|
+
"FULL",
|
|
413
|
+
"OUTER",
|
|
414
|
+
"GROUP",
|
|
415
|
+
"BY",
|
|
416
|
+
"ORDER",
|
|
417
|
+
"HAVING",
|
|
418
|
+
"DISTINCT",
|
|
419
|
+
"LIMIT",
|
|
420
|
+
"OFFSET",
|
|
421
|
+
"AS",
|
|
422
|
+
"AND",
|
|
423
|
+
"OR",
|
|
424
|
+
"NOT",
|
|
425
|
+
"IN",
|
|
426
|
+
"LIKE",
|
|
427
|
+
"IS",
|
|
428
|
+
"NULL",
|
|
429
|
+
"CASE",
|
|
430
|
+
"WHEN",
|
|
431
|
+
"THEN",
|
|
432
|
+
"ELSE",
|
|
433
|
+
"END",
|
|
434
|
+
"UNION",
|
|
435
|
+
"ALL",
|
|
436
|
+
"EXISTS",
|
|
437
|
+
"BETWEEN"
|
|
438
|
+
];
|
|
439
|
+
let formatted = unformatted;
|
|
440
|
+
// 예약어를 대문자로 변환
|
|
441
|
+
keywords.forEach((keyword)=>{
|
|
442
|
+
const regex = new RegExp(`\\b${keyword}\\b`, "gi");
|
|
443
|
+
formatted = formatted.replace(regex, keyword.toUpperCase());
|
|
444
|
+
});
|
|
445
|
+
// 주요 절 앞에 줄바꿈 추가
|
|
446
|
+
const majorClauses = [
|
|
447
|
+
"SELECT",
|
|
448
|
+
"FROM",
|
|
449
|
+
"WHERE",
|
|
450
|
+
"GROUP BY",
|
|
451
|
+
"ORDER BY",
|
|
452
|
+
"HAVING",
|
|
453
|
+
"LIMIT",
|
|
454
|
+
"UNION"
|
|
455
|
+
];
|
|
456
|
+
majorClauses.forEach((clause)=>{
|
|
457
|
+
const regex = new RegExp(`\\s+(${clause})\\s+`, "gi");
|
|
458
|
+
formatted = formatted.replace(regex, `\n${clause.toUpperCase()} `);
|
|
459
|
+
});
|
|
460
|
+
// JOIN 절 처리
|
|
461
|
+
formatted = formatted.replace(/\s+((?:INNER|LEFT|RIGHT|FULL OUTER)\s+)?JOIN\s+/gi, "\n$1JOIN ");
|
|
462
|
+
// AND, OR 조건 처리
|
|
463
|
+
formatted = formatted.replace(/\s+(AND|OR)\s+/gi, "\n $1 ");
|
|
464
|
+
// 괄호 처리 및 들여쓰기
|
|
465
|
+
const lines = formatted.split("\n");
|
|
466
|
+
const indentedLines = [];
|
|
467
|
+
let indentLevel = 0;
|
|
468
|
+
for (const line of lines){
|
|
469
|
+
const trimmedLine = line.trim();
|
|
470
|
+
if (!trimmedLine) continue;
|
|
471
|
+
// 닫는 괄호가 있으면 들여쓰기 레벨 감소
|
|
472
|
+
const closingParens = (trimmedLine.match(/\)/g) || []).length;
|
|
473
|
+
const openingParens = (trimmedLine.match(/\(/g) || []).length;
|
|
474
|
+
if (closingParens > 0 && openingParens === 0) {
|
|
475
|
+
indentLevel = Math.max(0, indentLevel - closingParens);
|
|
476
|
+
}
|
|
477
|
+
// 현재 들여쓰기 적용
|
|
478
|
+
const indent = " ".repeat(indentLevel);
|
|
479
|
+
indentedLines.push(indent + trimmedLine);
|
|
480
|
+
// 여는 괄호가 있으면 들여쓰기 레벨 증가
|
|
481
|
+
if (openingParens > closingParens) {
|
|
482
|
+
indentLevel += openingParens - closingParens;
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
return indentedLines.join("\n").trim();
|
|
486
|
+
}
|
|
487
|
+
// Knex 쿼리 빌더 직접 접근
|
|
488
|
+
raw() {
|
|
489
|
+
return this.knexQuery;
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
export class WhereGroup {
|
|
493
|
+
builder;
|
|
494
|
+
constructor(builder){
|
|
495
|
+
this.builder = builder;
|
|
496
|
+
}
|
|
497
|
+
where(...args) {
|
|
498
|
+
this.builder.where(args[0], ...args.slice(1));
|
|
499
|
+
return this;
|
|
500
|
+
}
|
|
501
|
+
orWhere(...args) {
|
|
502
|
+
this.builder.orWhere(args[0], ...args.slice(1));
|
|
503
|
+
return this;
|
|
504
|
+
}
|
|
505
|
+
whereGroup(callback) {
|
|
506
|
+
this.builder.where((subBuilder)=>{
|
|
507
|
+
const subGroup = new WhereGroup(subBuilder);
|
|
508
|
+
callback(subGroup);
|
|
509
|
+
});
|
|
510
|
+
return this;
|
|
511
|
+
}
|
|
512
|
+
orWhereGroup(callback) {
|
|
513
|
+
this.builder.orWhere((subBuilder)=>{
|
|
514
|
+
const subGroup = new WhereGroup(subBuilder);
|
|
515
|
+
callback(subGroup);
|
|
516
|
+
});
|
|
517
|
+
return this;
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
export class JoinClauseGroup {
|
|
521
|
+
callback;
|
|
522
|
+
constructor(callback){
|
|
523
|
+
this.callback = callback;
|
|
524
|
+
}
|
|
525
|
+
// ON(AND) 구현
|
|
526
|
+
on(...args) {
|
|
527
|
+
this.callback.on(...args);
|
|
528
|
+
return this;
|
|
529
|
+
}
|
|
530
|
+
// ON(OR) 구현
|
|
531
|
+
orOn(...args) {
|
|
532
|
+
this.callback.orOn(...args);
|
|
533
|
+
return this;
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
/*
|
|
537
|
+
TResolved: 쿼리 실행 후 반환될 결과 타입
|
|
538
|
+
TReturning: RETURNING 절에 사용될 타입
|
|
539
|
+
*/ export class ResolvedPuri {
|
|
540
|
+
knexQuery;
|
|
541
|
+
knex;
|
|
542
|
+
constructor(knexQuery, knex){
|
|
543
|
+
this.knexQuery = knexQuery;
|
|
544
|
+
this.knex = knex;
|
|
545
|
+
}
|
|
546
|
+
toQuery() {
|
|
547
|
+
return this.knexQuery.toQuery();
|
|
548
|
+
}
|
|
549
|
+
debug() {
|
|
550
|
+
console.log(`${chalk.cyan("[Puri Debug]")} ${chalk.yellow(this.toQuery())}`);
|
|
551
|
+
return this;
|
|
552
|
+
}
|
|
553
|
+
then(onfulfilled, onrejected) {
|
|
554
|
+
Naite.t("puri:executed-query", this.toQuery());
|
|
555
|
+
return this.knexQuery.then(onfulfilled, onrejected);
|
|
556
|
+
}
|
|
557
|
+
catch(onrejected) {
|
|
558
|
+
return this.knexQuery.catch(onrejected);
|
|
559
|
+
}
|
|
560
|
+
finally(onfinally) {
|
|
561
|
+
return this.knexQuery.finally(onfinally);
|
|
562
|
+
}
|
|
563
|
+
// ON CONFLICT - 컬럼 기반
|
|
564
|
+
onConflict(columns, action) {
|
|
565
|
+
const target = Array.isArray(columns) ? columns : [
|
|
566
|
+
columns
|
|
567
|
+
];
|
|
568
|
+
if (!action || action === "nothing") {
|
|
569
|
+
// DO NOTHING
|
|
570
|
+
this.knexQuery.onConflict(target).ignore();
|
|
571
|
+
} else {
|
|
572
|
+
// DO UPDATE
|
|
573
|
+
const { update } = action;
|
|
574
|
+
// action.update 배열 형태 : ["name", "email"]
|
|
575
|
+
if (Array.isArray(update)) {
|
|
576
|
+
this.knexQuery.onConflict(target).merge(update);
|
|
577
|
+
} else {
|
|
578
|
+
// action.update 객체 형태: { name: "John", count: raw(...) }
|
|
579
|
+
const mergeObj = {};
|
|
580
|
+
for (const [key, value] of Object.entries(update)){
|
|
581
|
+
if (value && typeof value === "object" && "_type" in value && value._type === "sql_expression") {
|
|
582
|
+
// SqlExpression → knex.raw()로 변환
|
|
583
|
+
mergeObj[key] = this.knex.raw(value._sql);
|
|
584
|
+
} else {
|
|
585
|
+
// 일반 값
|
|
586
|
+
mergeObj[key] = value;
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
this.knexQuery.onConflict(target).merge(mergeObj);
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
return this;
|
|
593
|
+
}
|
|
594
|
+
// RETURNING 구현
|
|
595
|
+
returning(columnOrColumns) {
|
|
596
|
+
this.knexQuery.returning(columnOrColumns);
|
|
597
|
+
return new ResolvedPuri(this.knexQuery, this.knex);
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9kYXRhYmFzZS9wdXJpLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKiBiaW9tZS1pZ25vcmUtYWxsIGxpbnQvc3VzcGljaW91cy9ub1RoZW5Qcm9wZXJ0eTogUHVyaeuKlCB0aGVuYWJsZSDsnbjthLDtjpjsnbTsiqTrpbwg6rWs7ZiE7ZWY6rOgIOyeiOyKteuLiOuLpC4gKi9cbi8qKiBiaW9tZS1pZ25vcmUtYWxsIGxpbnQvc3VzcGljaW91cy9ub0V4cGxpY2l0QW55OiBQdXJp64qUIOuLpOyWke2VnCDtg4DsnoXsnYQg7IKs7Jqp7ZWY6rOgIOyeiOyKteuLiOuLpC4gKi9cblxuaW1wb3J0IGFzc2VydCBmcm9tIFwiYXNzZXJ0XCI7XG5pbXBvcnQgY2hhbGsgZnJvbSBcImNoYWxrXCI7XG5pbXBvcnQgdHlwZSB7IEtuZXggfSBmcm9tIFwia25leFwiO1xuaW1wb3J0IHsgTmFpdGUgfSBmcm9tIFwiLi4vbmFpdGUvbmFpdGVcIjtcbmltcG9ydCB0eXBlIHtcbiAgQXZhaWxhYmxlQ29sdW1ucyxcbiAgQ29sdW1uS2V5cyxcbiAgQ29tcGFyaXNvbk9wZXJhdG9yLFxuICBFeHBhbmQsXG4gIEV4dHJhY3RDb2x1bW5UeXBlLFxuICBGdWxsdGV4dENvbHVtbnMsXG4gIEluc2VydERhdGEsXG4gIEluc2VydFJlc3VsdCxcbiAgT25Db25mbGljdEFjdGlvbixcbiAgUGFyc2VTZWxlY3RPYmplY3QsXG4gIFJlc3VsdEF2YWlsYWJsZUNvbHVtbnMsXG4gIFNlbGVjdE9iamVjdCxcbiAgU2luZ2xlVGFibGVWYWx1ZSxcbiAgU3FsRXhwcmVzc2lvbixcbiAgV2hlcmVDb25kaXRpb24sXG59IGZyb20gXCIuL3B1cmkudHlwZXNcIjtcbmltcG9ydCB0eXBlIHsgQ2xlYXJTdGF0ZW1lbnRzIH0gZnJvbSBcIi4vcHVyaS1zdWJzZXQudHlwZXNcIjtcblxuZXhwb3J0IGNsYXNzIFB1cmk8VFNjaGVtYSwgVFRhYmxlcyBleHRlbmRzIFJlY29yZDxzdHJpbmcsIGFueT4sIFRSZXN1bHQ+IHtcbiAgcHJpdmF0ZSBrbmV4UXVlcnk6IEtuZXguUXVlcnlCdWlsZGVyO1xuXG4gIC8vIOyDneyEseyekCDsi5zqt7jri4jsspjrk6RcbiAgY29uc3RydWN0b3Ioa25leDogS25leCwgdGFibGVOYW1lOiBzdHJpbmcpO1xuICBjb25zdHJ1Y3RvcihrbmV4OiBLbmV4LCB0YWJsZVNwZWM6IFJlY29yZDxzdHJpbmcsIHN0cmluZyB8IFB1cmk8VFNjaGVtYSwgYW55LCBhbnk+Pik7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHB1YmxpYyBrbmV4OiBLbmV4LFxuICAgIHRhYmxlTmFtZU9yU3BlYzogYW55LFxuICApIHtcbiAgICBpZiAodHlwZW9mIHRhYmxlTmFtZU9yU3BlYyA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgLy8gQ2FzZTogbmV3IFB1cmkoa25leCwgXCJ1c2Vyc1wiKVxuICAgICAgdGhpcy5rbmV4UXVlcnkgPSB0aGlzLmtuZXgodGFibGVOYW1lT3JTcGVjKS5mcm9tKHRhYmxlTmFtZU9yU3BlYyk7XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgdGFibGVOYW1lT3JTcGVjID09PSBcIm9iamVjdFwiKSB7XG4gICAgICBjb25zdCBlbnRyaWVzID0gT2JqZWN0LmVudHJpZXModGFibGVOYW1lT3JTcGVjKTtcbiAgICAgIGlmIChlbnRyaWVzLmxlbmd0aCAhPT0gMSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUYWJsZSBzcGVjIG11c3QgaGF2ZSBleGFjdGx5IG9uZSBlbnRyeVwiKTtcbiAgICAgIH1cbiAgICAgIGFzc2VydChlbnRyaWVzWzBdKTtcbiAgICAgIGNvbnN0IFthbGlhcywgc3BlY10gPSBlbnRyaWVzWzBdO1xuICAgICAgaWYgKHR5cGVvZiBzcGVjID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgIHRoaXMua25leFF1ZXJ5ID0gdGhpcy5rbmV4KHNwZWMpLmZyb20oeyBbYWxpYXNdOiBzcGVjIH0pO1xuICAgICAgfSBlbHNlIGlmIChzcGVjIGluc3RhbmNlb2YgUHVyaSkge1xuICAgICAgICBjb25zdCBzdWJxdWVyeUJ1aWxkZXIgPSBzcGVjLnJhdygpO1xuICAgICAgICB0aGlzLmtuZXhRdWVyeSA9IHRoaXMua25leC5mcm9tKHN1YnF1ZXJ5QnVpbGRlci5hcyhhbGlhcykpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiSW52YWxpZCB0YWJsZSBzcGVjaWZpY2F0aW9uXCIpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJJbnZhbGlkIHRhYmxlIHNwZWNpZmljYXRpb25cIik7XG4gICAgfVxuICB9XG5cbiAgLy8gU3RhdGljIFNRTCBoZWxwZXIgZnVuY3Rpb25zIGZvciBTRUxFQ1RcbiAgc3RhdGljIGNvdW50KGNvbHVtbjogc3RyaW5nID0gXCIqXCIpOiBTcWxFeHByZXNzaW9uPFwibnVtYmVyXCI+IHtcbiAgICByZXR1cm4ge1xuICAgICAgX3R5cGU6IFwic3FsX2V4cHJlc3Npb25cIixcbiAgICAgIF9yZXR1cm46IFwibnVtYmVyXCIsXG4gICAgICBfc3FsOiBgQ09VTlQoJHtjb2x1bW59KTo6aW50ZWdlcmAsXG4gICAgfTtcbiAgfVxuICBzdGF0aWMgc3VtKGNvbHVtbjogc3RyaW5nKTogU3FsRXhwcmVzc2lvbjxcIm51bWJlclwiPiB7XG4gICAgcmV0dXJuIHtcbiAgICAgIF90eXBlOiBcInNxbF9leHByZXNzaW9uXCIsXG4gICAgICBfcmV0dXJuOiBcIm51bWJlclwiLFxuICAgICAgX3NxbDogYFNVTSgke2NvbHVtbn0pYCxcbiAgICB9O1xuICB9XG4gIHN0YXRpYyBhdmcoY29sdW1uOiBzdHJpbmcpOiBTcWxFeHByZXNzaW9uPFwibnVtYmVyXCI+IHtcbiAgICByZXR1cm4ge1xuICAgICAgX3R5cGU6IFwic3FsX2V4cHJlc3Npb25cIixcbiAgICAgIF9yZXR1cm46IFwibnVtYmVyXCIsXG4gICAgICBfc3FsOiBgQVZHKCR7Y29sdW1ufSlgLFxuICAgIH07XG4gIH1cbiAgc3RhdGljIG1heChjb2x1bW46IHN0cmluZyk6IFNxbEV4cHJlc3Npb248XCJudW1iZXJcIj4ge1xuICAgIHJldHVybiB7XG4gICAgICBfdHlwZTogXCJzcWxfZXhwcmVzc2lvblwiLFxuICAgICAgX3JldHVybjogXCJudW1iZXJcIixcbiAgICAgIF9zcWw6IGBNQVgoJHtjb2x1bW59KWAsXG4gICAgfTtcbiAgfVxuICBzdGF0aWMgbWluKGNvbHVtbjogc3RyaW5nKTogU3FsRXhwcmVzc2lvbjxcIm51bWJlclwiPiB7XG4gICAgcmV0dXJuIHtcbiAgICAgIF90eXBlOiBcInNxbF9leHByZXNzaW9uXCIsXG4gICAgICBfcmV0dXJuOiBcIm51bWJlclwiLFxuICAgICAgX3NxbDogYE1JTigke2NvbHVtbn0pYCxcbiAgICB9O1xuICB9XG4gIHN0YXRpYyBjb25jYXQoLi4uYXJnczogc3RyaW5nW10pOiBTcWxFeHByZXNzaW9uPFwic3RyaW5nXCI+IHtcbiAgICByZXR1cm4ge1xuICAgICAgX3R5cGU6IFwic3FsX2V4cHJlc3Npb25cIixcbiAgICAgIF9yZXR1cm46IFwic3RyaW5nXCIsXG4gICAgICBfc3FsOiBgQ09OQ0FUKCR7YXJncy5qb2luKFwiLCBcIil9KWAsXG4gICAgfTtcbiAgfVxuICBzdGF0aWMgdXBwZXIoY29sdW1uOiBzdHJpbmcpOiBTcWxFeHByZXNzaW9uPFwic3RyaW5nXCI+IHtcbiAgICByZXR1cm4ge1xuICAgICAgX3R5cGU6IFwic3FsX2V4cHJlc3Npb25cIixcbiAgICAgIF9yZXR1cm46IFwic3RyaW5nXCIsXG4gICAgICBfc3FsOiBgVVBQRVIoJHtjb2x1bW59KWAsXG4gICAgfTtcbiAgfVxuICBzdGF0aWMgbG93ZXIoY29sdW1uOiBzdHJpbmcpOiBTcWxFeHByZXNzaW9uPFwic3RyaW5nXCI+IHtcbiAgICByZXR1cm4ge1xuICAgICAgX3R5cGU6IFwic3FsX2V4cHJlc3Npb25cIixcbiAgICAgIF9yZXR1cm46IFwic3RyaW5nXCIsXG4gICAgICBfc3FsOiBgTE9XRVIoJHtjb2x1bW59KWAsXG4gICAgfTtcbiAgfVxuXG4gIC8vIFJhdyBmdW5jdGlvbnMgZm9yIFNFTEVDVFxuICBzdGF0aWMgcmF3U3RyaW5nKHNxbDogc3RyaW5nKTogU3FsRXhwcmVzc2lvbjxcInN0cmluZ1wiPiB7XG4gICAgcmV0dXJuIHsgX3R5cGU6IFwic3FsX2V4cHJlc3Npb25cIiwgX3JldHVybjogXCJzdHJpbmdcIiwgX3NxbDogc3FsIH07XG4gIH1cbiAgc3RhdGljIHJhd051bWJlcihzcWw6IHN0cmluZyk6IFNxbEV4cHJlc3Npb248XCJudW1iZXJcIj4ge1xuICAgIHJldHVybiB7IF90eXBlOiBcInNxbF9leHByZXNzaW9uXCIsIF9yZXR1cm46IFwibnVtYmVyXCIsIF9zcWw6IHNxbCB9O1xuICB9XG4gIHN0YXRpYyByYXdCb29sZWFuKHNxbDogc3RyaW5nKTogU3FsRXhwcmVzc2lvbjxcImJvb2xlYW5cIj4ge1xuICAgIHJldHVybiB7IF90eXBlOiBcInNxbF9leHByZXNzaW9uXCIsIF9yZXR1cm46IFwiYm9vbGVhblwiLCBfc3FsOiBzcWwgfTtcbiAgfVxuICBzdGF0aWMgcmF3RGF0ZShzcWw6IHN0cmluZyk6IFNxbEV4cHJlc3Npb248XCJkYXRlXCI+IHtcbiAgICByZXR1cm4geyBfdHlwZTogXCJzcWxfZXhwcmVzc2lvblwiLCBfcmV0dXJuOiBcImRhdGVcIiwgX3NxbDogc3FsIH07XG4gIH1cblxuICAvLyBTRUxFQ1QgKG92ZXJ3cml0ZSlcbiAgc2VsZWN0PFRTZWxlY3QgZXh0ZW5kcyBTZWxlY3RPYmplY3Q8VFRhYmxlcz4+KFxuICAgIHNlbGVjdE9iajogVFNlbGVjdCxcbiAgKTogUHVyaTxUU2NoZW1hLCBUVGFibGVzLCBQYXJzZVNlbGVjdE9iamVjdDxUVGFibGVzLCBUU2VsZWN0Pj4ge1xuICAgIGNvbnN0IHNlbGVjdENsYXVzZXM6IChzdHJpbmcgfCBLbmV4LlJhdylbXSA9IFtdO1xuXG4gICAgZm9yIChjb25zdCBbYWxpYXMsIGNvbHVtbk9yRnVuY3Rpb25dIG9mIE9iamVjdC5lbnRyaWVzKHNlbGVjdE9iaikpIHtcbiAgICAgIGlmICh0eXBlb2YgY29sdW1uT3JGdW5jdGlvbiA9PT0gXCJvYmplY3RcIiAmJiBjb2x1bW5PckZ1bmN0aW9uLl90eXBlID09PSBcInNxbF9leHByZXNzaW9uXCIpIHtcbiAgICAgICAgLy8gU1FMIO2VqOyImOyduCDqsr3smrBcbiAgICAgICAgc2VsZWN0Q2xhdXNlcy5wdXNoKHRoaXMua25leC5yYXcoYCR7Y29sdW1uT3JGdW5jdGlvbi5fc3FsfSBhcyAke2FsaWFzfWApKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIOydvOuwmCDsu6zrn7zsnbgg6rK97JqwXG4gICAgICAgIGNvbnN0IGNvbHVtblBhdGggPSBjb2x1bW5PckZ1bmN0aW9uIGFzIHN0cmluZztcbiAgICAgICAgaWYgKGFsaWFzID09PSBjb2x1bW5QYXRoKSB7XG4gICAgICAgICAgLy8gYWxpYXPsmYAg7Lus65+866qF7J20IOqwmeycvOuptCBhbGlhcyDsg53rnrVcbiAgICAgICAgICBzZWxlY3RDbGF1c2VzLnB1c2goY29sdW1uUGF0aCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gYWxpYXMg7KeA7KCVXG4gICAgICAgICAgc2VsZWN0Q2xhdXNlcy5wdXNoKGAke2NvbHVtblBhdGh9IGFzICR7YWxpYXN9YCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLmtuZXhRdWVyeS5zZWxlY3Qoc2VsZWN0Q2xhdXNlcyk7XG4gICAgcmV0dXJuIHRoaXMgYXMgYW55O1xuICB9XG5cbiAgLy8gU0VMRUNUIChzZWxlY3TripQgb3ZlcndyaXRlLCBhcHBlbmRTZWxlY3TripQgYXBwZW5kKVxuICBhcHBlbmRTZWxlY3Q8VFNlbGVjdCBleHRlbmRzIFNlbGVjdE9iamVjdDxUVGFibGVzPj4oXG4gICAgc2VsZWN0T2JqOiBUU2VsZWN0LFxuICApOiBQdXJpPFRTY2hlbWEsIFRUYWJsZXMsIFRSZXN1bHQgJiBQYXJzZVNlbGVjdE9iamVjdDxUVGFibGVzLCBUU2VsZWN0Pj4ge1xuICAgIHJldHVybiB0aGlzLnNlbGVjdChzZWxlY3RPYmopIGFzIGFueTtcbiAgfVxuXG4gIC8vIFNFTEVDVCAqXG4gIHNlbGVjdEFsbCgpOiB0aGlzIHtcbiAgICB0aGlzLmtuZXhRdWVyeS5zZWxlY3QoXCIqXCIpO1xuICAgIHJldHVybiB0aGlzIGFzIGFueTtcbiAgfVxuXG4gIC8vIENMRUFSXG4gIGNsZWFyKHN0YXRlbWVudDogQ2xlYXJTdGF0ZW1lbnRzKTogdGhpcyB7XG4gICAgdGhpcy5rbmV4UXVlcnkuY2xlYXIoc3RhdGVtZW50KTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8vIGtuZXjsl5Ag7JeG7Ja07IScIOyngeygkSDqtaztmITtlahcbiAgY2xlYXJKb2luKGFsaWFzOiBzdHJpbmcpOiB0aGlzIHtcbiAgICAodGhpcy5rbmV4UXVlcnkgYXMgYW55KS5fc3RhdGVtZW50cyA9ICh0aGlzLmtuZXhRdWVyeSBhcyBhbnkpLl9zdGF0ZW1lbnRzLmZpbHRlcigoczogYW55KSA9PiB7XG4gICAgICBpZiAoXCJqb2luVHlwZVwiIGluIHMpIHtcbiAgICAgICAgY29uc3QgW19hbGlhcywgX3RhYmxlXSA9IE9iamVjdC5lbnRyaWVzKHMudGFibGUpWzBdO1xuICAgICAgICByZXR1cm4gX2FsaWFzICE9PSBhbGlhcztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLy8gSk9JTjog7ISc67iM7L+866asICsgQWxpYXNcbiAgam9pbjxUSm9pbkFsaWFzIGV4dGVuZHMgc3RyaW5nLCBUU3ViUmVzdWx0PihcbiAgICB0YWJsZVNwZWM6IHsgW0sgaW4gVEpvaW5BbGlhc106IFB1cmk8VFNjaGVtYSwgYW55LCBUU3ViUmVzdWx0PiB9LFxuICAgIGxlZnQ6IEF2YWlsYWJsZUNvbHVtbnM8VFRhYmxlcz4sXG4gICAgcmlnaHQ6IGAke1RKb2luQWxpYXN9LiR7Q29sdW1uS2V5czxUU3ViUmVzdWx0Pn1gLFxuICApOiBQdXJpPFxuICAgIFRTY2hlbWEsXG4gICAgVFRhYmxlcyAmIFJlY29yZDxUSm9pbkFsaWFzLCBUU3ViUmVzdWx0PiwgLy8g7ISc67iM7L+866as7J2YIFRSZXN1bHRcbiAgICBUUmVzdWx0XG4gID47XG4gIC8vIEpPSU46IO2FjOydtOu4lCArIEFsaWFzXG4gIGpvaW48VEpvaW5UYWJsZSBleHRlbmRzIGtleW9mIFRTY2hlbWEsIFRKb2luQWxpYXMgZXh0ZW5kcyBzdHJpbmc+KFxuICAgIHRhYmxlU3BlYzogeyBbSyBpbiBUSm9pbkFsaWFzXTogVEpvaW5UYWJsZSB9LFxuICAgIGxlZnQ6IEF2YWlsYWJsZUNvbHVtbnM8VFRhYmxlcz4sXG4gICAgcmlnaHQ6IGAke1RKb2luQWxpYXN9LiR7Q29sdW1uS2V5czxUU2NoZW1hW1RKb2luVGFibGVdPn1gLFxuICApOiBQdXJpPFxuICAgIFRTY2hlbWEsXG4gICAgVFRhYmxlcyAmIFJlY29yZDxUSm9pbkFsaWFzLCBUU2NoZW1hW1RKb2luVGFibGVdPiwgLy8gVFRhYmxlcyDtmZXsnqUhXG4gICAgVFJlc3VsdFxuICA+O1xuICAvLyBKT0lOOiDthYzsnbTruJTrqoVcbiAgam9pbjxUSm9pblRhYmxlIGV4dGVuZHMga2V5b2YgVFNjaGVtYT4oXG4gICAgdGFibGVOYW1lOiBUSm9pblRhYmxlLFxuICAgIGxlZnQ6IEF2YWlsYWJsZUNvbHVtbnM8VFRhYmxlcz4sXG4gICAgcmlnaHQ6IGAke1RKb2luVGFibGUgJiBzdHJpbmd9LiR7Q29sdW1uS2V5czxUU2NoZW1hW1RKb2luVGFibGVdPn1gLFxuICApOiBQdXJpPFxuICAgIFRTY2hlbWEsXG4gICAgVFRhYmxlcyAmIFJlY29yZDxUSm9pblRhYmxlLCBUU2NoZW1hW1RKb2luVGFibGVdPiwgLy8g7YWM7J2067iU66qF7J20IO2CpFxuICAgIFRSZXN1bHRcbiAgPjtcbiAgLy8gSk9JTjog7ISc67iM7L+866asICsgQWxpYXMgKyDsvZzrsLFcbiAgam9pbjxUSm9pbkFsaWFzIGV4dGVuZHMgc3RyaW5nLCBUU3ViUmVzdWx0PihcbiAgICB0YWJsZVNwZWM6IHsgW0sgaW4gVEpvaW5BbGlhc106IFB1cmk8VFNjaGVtYSwgYW55LCBUU3ViUmVzdWx0PiB9LFxuICAgIGNhbGxiYWNrOiAoajogSm9pbkNsYXVzZUdyb3VwPFRUYWJsZXMsIFJlY29yZDxUSm9pbkFsaWFzLCBUU3ViUmVzdWx0Pj4pID0+IHZvaWQsXG4gICk6IFB1cmk8VFNjaGVtYSwgVFRhYmxlcyAmIFJlY29yZDxUSm9pbkFsaWFzLCBUU3ViUmVzdWx0PiwgVFJlc3VsdD47XG4gIC8vIEpPSU46IO2FjOydtOu4lCArIEFsaWFzICsg7L2c67CxXG4gIGpvaW48VEpvaW5UYWJsZSBleHRlbmRzIGtleW9mIFRTY2hlbWEsIFRKb2luQWxpYXMgZXh0ZW5kcyBzdHJpbmc+KFxuICAgIHRhYmxlU3BlYzogeyBbSyBpbiBUSm9pbkFsaWFzXTogVEpvaW5UYWJsZSB9LFxuICAgIGNhbGxiYWNrOiAoajogSm9pbkNsYXVzZUdyb3VwPFRUYWJsZXMsIFJlY29yZDxUSm9pbkFsaWFzLCBUU2NoZW1hW1RKb2luVGFibGVdPj4pID0+IHZvaWQsXG4gICk6IFB1cmk8VFNjaGVtYSwgVFRhYmxlcyAmIFJlY29yZDxUSm9pbkFsaWFzLCBUU2NoZW1hW1RKb2luVGFibGVdPiwgVFJlc3VsdD47XG4gIC8vIEpPSU46IO2FjOydtOu4lOuqhSArIOy9nOuwsVxuICBqb2luPFRKb2luVGFibGUgZXh0ZW5kcyBrZXlvZiBUU2NoZW1hPihcbiAgICB0YWJsZU5hbWU6IFRKb2luVGFibGUsXG4gICAgY2FsbGJhY2s6IChqOiBKb2luQ2xhdXNlR3JvdXA8VFRhYmxlcywgUmVjb3JkPFRKb2luVGFibGUsIFRTY2hlbWFbVEpvaW5UYWJsZV0+PikgPT4gdm9pZCxcbiAgKTogUHVyaTxUU2NoZW1hLCBUVGFibGVzICYgUmVjb3JkPFRKb2luVGFibGUsIFRTY2hlbWFbVEpvaW5UYWJsZV0+LCBUUmVzdWx0PjtcbiAgLy8gSk9JTiDsi6TsoJwg6rWs7ZiEXG4gIGpvaW4odGFibGVOYW1lT3JTcGVjOiBhbnksIC4uLmFyZ3M6IGFueVtdKTogYW55IHtcbiAgICByZXR1cm4gdGhpcy5fX2NvbW1vbkpvaW4oXCJqb2luXCIsIHRhYmxlTmFtZU9yU3BlYywgLi4uYXJncyk7XG4gIH1cblxuICAvLyBMRUZUIEpPSU46IOyEnOu4jOy/vOumrCArIEFsaWFzXG4gIGxlZnRKb2luPFRKb2luQWxpYXMgZXh0ZW5kcyBzdHJpbmcsIFRTdWJSZXN1bHQ+KFxuICAgIHRhYmxlU3BlYzogeyBbSyBpbiBUSm9pbkFsaWFzXTogUHVyaTxUU2NoZW1hLCBhbnksIFRTdWJSZXN1bHQ+IH0sXG4gICAgbGVmdDogQXZhaWxhYmxlQ29sdW1uczxUVGFibGVzPixcbiAgICByaWdodDogYCR7VEpvaW5BbGlhc30uJHtDb2x1bW5LZXlzPFRTdWJSZXN1bHQ+fWAsXG4gICk6IFB1cmk8XG4gICAgVFNjaGVtYSxcbiAgICBUVGFibGVzICYgUmVjb3JkPFRKb2luQWxpYXMsIFRTdWJSZXN1bHQ+LCAvLyDshJzruIzsv7zrpqzsnZggVFJlc3VsdFxuICAgIFRSZXN1bHRcbiAgPjtcbiAgLy8gTEVGVCBKT0lOOiDthYzsnbTruJQgKyBBbGlhc1xuICBsZWZ0Sm9pbjxUSm9pblRhYmxlIGV4dGVuZHMga2V5b2YgVFNjaGVtYSwgVEpvaW5BbGlhcyBleHRlbmRzIHN0cmluZz4oXG4gICAgdGFibGVTcGVjOiB7IFtLIGluIFRKb2luQWxpYXNdOiBUSm9pblRhYmxlIH0sXG4gICAgbGVmdDogQXZhaWxhYmxlQ29sdW1uczxUVGFibGVzPixcbiAgICByaWdodDogYCR7VEpvaW5BbGlhc30uJHtDb2x1bW5LZXlzPFRTY2hlbWFbVEpvaW5UYWJsZV0+fWAsXG4gICk6IFB1cmk8XG4gICAgVFNjaGVtYSxcbiAgICBUVGFibGVzICYgUmVjb3JkPFRKb2luQWxpYXMsIFRTY2hlbWFbVEpvaW5UYWJsZV0+LCAvLyBUVGFibGVzIO2ZleyepSFcbiAgICBUUmVzdWx0XG4gID47XG4gIC8vIExFRlQgSk9JTjog7YWM7J2067iU66qFXG4gIGxlZnRKb2luPFRKb2luVGFibGUgZXh0ZW5kcyBrZXlvZiBUU2NoZW1hPihcbiAgICB0YWJsZU5hbWU6IFRKb2luVGFibGUsXG4gICAgbGVmdDogQXZhaWxhYmxlQ29sdW1uczxUVGFibGVzPixcbiAgICByaWdodDogYCR7VEpvaW5UYWJsZSAmIHN0cmluZ30uJHtDb2x1bW5LZXlzPFRTY2hlbWFbVEpvaW5UYWJsZV0+fWAsXG4gICk6IFB1cmk8XG4gICAgVFNjaGVtYSxcbiAgICBUVGFibGVzICYgUmVjb3JkPFRKb2luVGFibGUsIFRTY2hlbWFbVEpvaW5UYWJsZV0+LCAvLyDthYzsnbTruJTrqoXsnbQg7YKkXG4gICAgVFJlc3VsdFxuICA+O1xuICAvLyBMRUZUIEpPSU46IOyEnOu4jOy/vOumrCArIEFsaWFzICsg7L2c67CxXG4gIGxlZnRKb2luPFRKb2luQWxpYXMgZXh0ZW5kcyBzdHJpbmcsIFRTdWJSZXN1bHQ+KFxuICAgIHRhYmxlU3BlYzogeyBbSyBpbiBUSm9pbkFsaWFzXTogUHVyaTxUU2NoZW1hLCBhbnksIFRTdWJSZXN1bHQ+IH0sXG4gICAgY2FsbGJhY2s6IChqOiBKb2luQ2xhdXNlR3JvdXA8VFRhYmxlcywgUmVjb3JkPFRKb2luQWxpYXMsIFRTdWJSZXN1bHQ+PikgPT4gdm9pZCxcbiAgKTogUHVyaTxUU2NoZW1hLCBUVGFibGVzICYgUmVjb3JkPFRKb2luQWxpYXMsIFRTdWJSZXN1bHQ+LCBUUmVzdWx0PjtcbiAgLy8gTEVGVCBKT0lOOiDthYzsnbTruJQgKyBBbGlhcyArIOy9nOuwsVxuICBsZWZ0Sm9pbjxUSm9pblRhYmxlIGV4dGVuZHMga2V5b2YgVFNjaGVtYSwgVEpvaW5BbGlhcyBleHRlbmRzIHN0cmluZz4oXG4gICAgdGFibGVTcGVjOiB7IFtLIGluIFRKb2luQWxpYXNdOiBUSm9pblRhYmxlIH0sXG4gICAgY2FsbGJhY2s6IChqOiBKb2luQ2xhdXNlR3JvdXA8VFRhYmxlcywgUmVjb3JkPFRKb2luQWxpYXMsIFRTY2hlbWFbVEpvaW5UYWJsZV0+PikgPT4gdm9pZCxcbiAgKTogUHVyaTxUU2NoZW1hLCBUVGFibGVzICYgUmVjb3JkPFRKb2luQWxpYXMsIFRTY2hlbWFbVEpvaW5UYWJsZV0+LCBUUmVzdWx0PjtcbiAgLy8gTEVGVCBKT0lOOiDthYzsnbTruJTrqoUgKyDsvZzrsLFcbiAgbGVmdEpvaW48VEpvaW5UYWJsZSBleHRlbmRzIGtleW9mIFRTY2hlbWE+KFxuICAgIHRhYmxlTmFtZTogVEpvaW5UYWJsZSxcbiAgICBjYWxsYmFjazogKGo6IEpvaW5DbGF1c2VHcm91cDxUVGFibGVzLCBSZWNvcmQ8VEpvaW5UYWJsZSwgVFNjaGVtYVtUSm9pblRhYmxlXT4+KSA9PiB2b2lkLFxuICApOiBQdXJpPFRTY2hlbWEsIFRUYWJsZXMgJiBSZWNvcmQ8VEpvaW5UYWJsZSwgVFNjaGVtYVtUSm9pblRhYmxlXT4sIFRSZXN1bHQ+O1xuICAvLyBMRUZUIEpPSU4g7Iuk7KCcIOq1rO2YhFxuICBsZWZ0Sm9pbih0YWJsZU5hbWVPclNwZWM6IGFueSwgLi4uYXJnczogYW55W10pOiBhbnkge1xuICAgIHJldHVybiB0aGlzLl9fY29tbW9uSm9pbihcImxlZnRKb2luXCIsIHRhYmxlTmFtZU9yU3BlYywgLi4uYXJncyk7XG4gIH1cblxuICBfX2NvbW1vbkpvaW4oam9pblR5cGU6IFwiam9pblwiIHwgXCJsZWZ0Sm9pblwiLCB0YWJsZU5hbWVPclNwZWM6IGFueSwgLi4uYXJnczogYW55W10pOiB0aGlzIHtcbiAgICBpZiAodHlwZW9mIHRhYmxlTmFtZU9yU3BlYyA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgLy8gQ2FzZSAxOiBqb2luKFwicG9zdHNcIiwgLi4uKVxuICAgICAgY29uc3QgdGFibGVOYW1lID0gdGFibGVOYW1lT3JTcGVjO1xuXG4gICAgICBpZiAoYXJncy5sZW5ndGggPT09IDEgJiYgdHlwZW9mIGFyZ3NbMF0gPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAvLyBqb2luKFwicG9zdHNcIiwgY2FsbGJhY2spXG4gICAgICAgIGNvbnN0IGNhbGxiYWNrID0gYXJnc1swXTtcbiAgICAgICAgdGhpcy5rbmV4UXVlcnlbam9pblR5cGVdKHRhYmxlTmFtZSwgKGpvaW5DbGF1c2UpID0+IHtcbiAgICAgICAgICBjYWxsYmFjayhuZXcgSm9pbkNsYXVzZUdyb3VwKGpvaW5DbGF1c2UpKTtcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBqb2luKFwicG9zdHNcIiwgbGVmdCwgcmlnaHQpXG4gICAgICAgIGNvbnN0IFtsZWZ0LCByaWdodF0gPSBhcmdzO1xuICAgICAgICB0aGlzLmtuZXhRdWVyeVtqb2luVHlwZV0odGFibGVOYW1lLCBsZWZ0LCByaWdodCk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgdGFibGVOYW1lT3JTcGVjID09PSBcIm9iamVjdFwiKSB7XG4gICAgICAvLyBDYXNlIDI6IGpvaW4oeyBhbGlhczogXCJ0YWJsZVwiIH0sIC4uLikgb3Igam9pbih7IGFsaWFzOiBzdWJxdWVyeSB9LCAuLi4pXG4gICAgICBjb25zdCBlbnRyaWVzID0gT2JqZWN0LmVudHJpZXModGFibGVOYW1lT3JTcGVjKTtcbiAgICAgIGlmIChlbnRyaWVzLmxlbmd0aCAhPT0gMSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUYWJsZSBzcGVjIG11c3QgaGF2ZSBleGFjdGx5IG9uZSBlbnRyeVwiKTtcbiAgICAgIH1cbiAgICAgIGFzc2VydChlbnRyaWVzWzBdKTtcbiAgICAgIGNvbnN0IFtbYWxpYXMsIHNwZWNdXSA9IGVudHJpZXM7XG5cbiAgICAgIGlmICh0eXBlb2Ygc3BlYyA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgICAvLyDthYzsnbTruJQ6IGpvaW4oeyBwOiBcInBvc3RzXCIgfSwgLi4uKVxuICAgICAgICBpZiAoYXJncy5sZW5ndGggPT09IDEgJiYgdHlwZW9mIGFyZ3NbMF0gPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgIC8vIENhbGxiYWNrXG4gICAgICAgICAgY29uc3QgY2FsbGJhY2sgPSBhcmdzWzBdO1xuICAgICAgICAgIHRoaXMua25leFF1ZXJ5W2pvaW5UeXBlXSh7IFthbGlhc106IHNwZWMgfSwgKGpvaW5DbGF1c2UpID0+IHtcbiAgICAgICAgICAgIGNhbGxiYWNrKG5ldyBKb2luQ2xhdXNlR3JvdXAoam9pbkNsYXVzZSkpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIFNpbXBsZVxuICAgICAgICAgIGNvbnN0IFtsZWZ0LCByaWdodF0gPSBhcmdzO1xuICAgICAgICAgIHRoaXMua25leFF1ZXJ5W2pvaW5UeXBlXSh7IFthbGlhc106IHNwZWMgfSwgbGVmdCwgcmlnaHQpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKHNwZWMgaW5zdGFuY2VvZiBQdXJpKSB7XG4gICAgICAgIC8vIOyEnOu4jOy/vOumrDogam9pbih7IHNxOiBzdWJxdWVyeSB9LCAuLi4pXG4gICAgICAgIGlmIChhcmdzLmxlbmd0aCA9PT0gMSAmJiB0eXBlb2YgYXJnc1swXSA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgLy8gQ2FsbGJhY2tcbiAgICAgICAgICBjb25zdCBjYWxsYmFjayA9IGFyZ3NbMF07XG4gICAgICAgICAgdGhpcy5rbmV4UXVlcnlbam9pblR5cGVdKHNwZWMucmF3KCkuYXMoYWxpYXMpLCAoam9pbkNsYXVzZSkgPT4ge1xuICAgICAgICAgICAgY2FsbGJhY2sobmV3IEpvaW5DbGF1c2VHcm91cChqb2luQ2xhdXNlKSk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gU2ltcGxlXG4gICAgICAgICAgY29uc3QgW2xlZnQsIHJpZ2h0XSA9IGFyZ3M7XG4gICAgICAgICAgdGhpcy5rbmV4UXVlcnlbam9pblR5cGVdKHNwZWMucmF3KCkuYXMoYWxpYXMpLCBsZWZ0LCByaWdodCk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIkludmFsaWQgdGFibGUgc3BlY2lmaWNhdGlvblwiKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiSW52YWxpZCBhcmd1bWVudHNcIik7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvLyBXSEVSRTog6rCd7LK0IC0g7IKs7JqpOiAud2hlcmUoeyBcInUuaWRcIjogMSwgXCJ1LnN0YXR1c1wiOiBcImFjdGl2ZVwiIH0pXG4gIHdoZXJlKGNvbmRpdGlvbnM6IFdoZXJlQ29uZGl0aW9uPFRUYWJsZXM+KTogdGhpcztcbiAgLy8gV0hFUkU6IOy7rOufvCAtIOyCrOyaqTogLndoZXJlKFwidS5pZFwiLCAxKVxuICB3aGVyZTxUQ29sdW1uIGV4dGVuZHMgQXZhaWxhYmxlQ29sdW1uczxUVGFibGVzPj4oXG4gICAgY29sdW1uOiBUQ29sdW1uLFxuICAgIHZhbHVlOiBFeHRyYWN0Q29sdW1uVHlwZTxUVGFibGVzLCBUQ29sdW1uICYgc3RyaW5nPixcbiAgKTogdGhpcztcbiAgLy8gV0hFUkU6IOy7rOufvCAtIOyCrOyaqTogLndoZXJlKFwidS5pZFwiLCBcIj5cIiwgMTApXG4gIHdoZXJlPFRDb2x1bW4gZXh0ZW5kcyBBdmFpbGFibGVDb2x1bW5zPFRUYWJsZXM+PihcbiAgICBjb2x1bW46IFRDb2x1bW4sXG4gICAgb3BlcmF0b3I6IENvbXBhcmlzb25PcGVyYXRvciB8IFwibGlrZVwiIHwgXCJub3QgbGlrZVwiLFxuICAgIHZhbHVlOiBFeHRyYWN0Q29sdW1uVHlwZTxUVGFibGVzLCBUQ29sdW1uICYgc3RyaW5nPixcbiAgKTogdGhpcztcbiAgLy8gV0hFUkU6IOy7rOufvCAtIOyCrOyaqTogLndoZXJlKFwidS5pZFwiLCBcImxpa2VcIiwgXCIldGVzdCVcIilcbiAgd2hlcmUoLi4uYXJnczogW2NvbHVtbk9yQ29uZGl0aW9uczogYW55LCBvcGVyYXRvck9yVmFsdWU/OiBhbnksIHZhbHVlPzogYW55XSk6IHRoaXMge1xuICAgIGNvbnN0IFtjb2x1bW5PckNvbmRpdGlvbnMsIG9wZXJhdG9yT3JWYWx1ZSwgdmFsdWVdID0gYXJncztcbiAgICBpZiAodHlwZW9mIGNvbHVtbk9yQ29uZGl0aW9ucyA9PT0gXCJvYmplY3RcIikge1xuICAgICAgdGhpcy5rbmV4UXVlcnkud2hlcmUoY29sdW1uT3JDb25kaXRpb25zKTtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgaWYgKG9wZXJhdG9yT3JWYWx1ZSA9PT0gbnVsbCkge1xuICAgICAgICB0aGlzLmtuZXhRdWVyeS53aGVyZU51bGwoY29sdW1uT3JDb25kaXRpb25zKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG4gICAgICB0aGlzLmtuZXhRdWVyeS53aGVyZShjb2x1bW5PckNvbmRpdGlvbnMsIG9wZXJhdG9yT3JWYWx1ZSk7XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgdmFsdWUgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgIGlmICh2YWx1ZSA9PT0gbnVsbCkge1xuICAgICAgICBpZiAob3BlcmF0b3JPclZhbHVlID09PSBcIiE9XCIpIHtcbiAgICAgICAgICB0aGlzLmtuZXhRdWVyeS53aGVyZU5vdE51bGwoY29sdW1uT3JDb25kaXRpb25zKTtcbiAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfSBlbHNlIGlmIChvcGVyYXRvck9yVmFsdWUgPT09IFwiPVwiKSB7XG4gICAgICAgICAgdGhpcy5rbmV4UXVlcnkud2hlcmVOdWxsKGNvbHVtbk9yQ29uZGl0aW9ucyk7XG4gICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHRoaXMua25leFF1ZXJ5LndoZXJlKGNvbHVtbk9yQ29uZGl0aW9ucywgb3BlcmF0b3JPclZhbHVlLCB2YWx1ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMua25leFF1ZXJ5LndoZXJlKGNvbHVtbk9yQ29uZGl0aW9ucyk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLy8gV0hFUkUgSU5cbiAgd2hlcmVJbjxUQ29sdW1uIGV4dGVuZHMgQXZhaWxhYmxlQ29sdW1uczxUVGFibGVzPj4oXG4gICAgY29sdW1uOiBUQ29sdW1uLFxuICAgIHZhbHVlczogRXh0cmFjdENvbHVtblR5cGU8VFRhYmxlcywgVENvbHVtbiAmIHN0cmluZz5bXSxcbiAgKTogUHVyaTxUU2NoZW1hLCBUVGFibGVzLCBUUmVzdWx0PiB7XG4gICAgdGhpcy5rbmV4UXVlcnkud2hlcmVJbihjb2x1bW4sIHZhbHVlcyk7XG4gICAgcmV0dXJuIHRoaXMgYXMgYW55O1xuICB9XG5cbiAgLy8gV0hFUkUgTk9UIElOXG4gIHdoZXJlTm90SW48VENvbHVtbiBleHRlbmRzIEF2YWlsYWJsZUNvbHVtbnM8VFRhYmxlcz4+KFxuICAgIGNvbHVtbjogVENvbHVtbixcbiAgICB2YWx1ZXM6IEV4dHJhY3RDb2x1bW5UeXBlPFRUYWJsZXMsIFRDb2x1bW4gJiBzdHJpbmc+W10sXG4gICk6IFB1cmk8VFNjaGVtYSwgVFRhYmxlcywgVFJlc3VsdD4ge1xuICAgIHRoaXMua25leFF1ZXJ5LndoZXJlTm90SW4oY29sdW1uLCB2YWx1ZXMpO1xuICAgIHJldHVybiB0aGlzIGFzIGFueTtcbiAgfVxuXG4gIC8vIFdIRVJFIE1BVENIXG4gIHdoZXJlTWF0Y2g8VENvbHVtbiBleHRlbmRzIEZ1bGx0ZXh0Q29sdW1uczxUVGFibGVzPj4oY29sdW1uOiBUQ29sdW1uLCB2YWx1ZTogc3RyaW5nKTogdGhpcyB7XG4gICAgdGhpcy5rbmV4UXVlcnkud2hlcmVSYXcoYE1BVENIICgke1N0cmluZyhjb2x1bW4pfSkgQUdBSU5TVCAoPylgLCBbdmFsdWVdKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8vIFdIRVJFIOq0hO2YuCDqt7jro7ntlZFcbiAgd2hlcmVHcm91cChjYWxsYmFjazogKGc6IFdoZXJlR3JvdXA8VFRhYmxlcz4pID0+IHZvaWQpOiB0aGlzIHtcbiAgICB0aGlzLmtuZXhRdWVyeS53aGVyZSgoYnVpbGRlcikgPT4ge1xuICAgICAgY29uc3QgZ3JvdXAgPSBuZXcgV2hlcmVHcm91cDxUVGFibGVzPihidWlsZGVyKTtcbiAgICAgIGNhbGxiYWNrKGdyb3VwKTtcbiAgICB9KTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuICBvcldoZXJlR3JvdXAoY2FsbGJhY2s6IChnOiBXaGVyZUdyb3VwPFRUYWJsZXM+KSA9PiB2b2lkKTogdGhpcyB7XG4gICAgdGhpcy5rbmV4UXVlcnkub3JXaGVyZSgoYnVpbGRlcikgPT4ge1xuICAgICAgY29uc3QgZ3JvdXAgPSBuZXcgV2hlcmVHcm91cDxUVGFibGVzPihidWlsZGVyKTtcbiAgICAgIGNhbGxiYWNrKGdyb3VwKTtcbiAgICB9KTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8vIE9SREVSIEJZXG4gIG9yZGVyQnk8VENvbHVtbiBleHRlbmRzIFJlc3VsdEF2YWlsYWJsZUNvbHVtbnM8VFRhYmxlcywgVFJlc3VsdD4+KFxuICAgIGNvbHVtbjogVENvbHVtbixcbiAgICBkaXJlY3Rpb246IFwiYXNjXCIgfCBcImRlc2NcIixcbiAgKTogdGhpcztcbiAgb3JkZXJCeShjb2x1bW46IHN0cmluZywgZGlyZWN0aW9uOiBcImFzY1wiIHwgXCJkZXNjXCIgPSBcImFzY1wiKTogdGhpcyB7XG4gICAgdGhpcy5rbmV4UXVlcnkub3JkZXJCeShjb2x1bW4sIGRpcmVjdGlvbik7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvLyDquLDrs7gg7L+866asIOuplOyEnOuTnOuTpFxuICBsaW1pdChjb3VudDogbnVtYmVyKTogdGhpcyB7XG4gICAgdGhpcy5rbmV4UXVlcnkubGltaXQoY291bnQpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgb2Zmc2V0KGNvdW50OiBudW1iZXIpOiB0aGlzIHtcbiAgICB0aGlzLmtuZXhRdWVyeS5vZmZzZXQoY291bnQpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLy8gR1JPVVAgQllcbiAgZ3JvdXBCeTxUQ29sdW1ucyBleHRlbmRzIFJlc3VsdEF2YWlsYWJsZUNvbHVtbnM8VFRhYmxlcywgVFJlc3VsdD4+KC4uLmNvbHVtbnM6IFRDb2x1bW5zW10pOiB0aGlzO1xuICBncm91cEJ5KC4uLmNvbHVtbnM6IHN0cmluZ1tdKTogdGhpcyB7XG4gICAgdGhpcy5rbmV4UXVlcnkuZ3JvdXBCeSguLi4oY29sdW1ucyBhcyBzdHJpbmdbXSkpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLy8gSEFWSU5HXG4gIGhhdmluZyhjb25kaXRpb246IHN0cmluZyk6IHRoaXM7XG4gIGhhdmluZzxUQ29sdW1uIGV4dGVuZHMgUmVzdWx0QXZhaWxhYmxlQ29sdW1uczxUVGFibGVzLCBUUmVzdWx0Pj4oXG4gICAgY29sdW1uOiBUQ29sdW1uLFxuICAgIG9wZXJhdG9yOiBDb21wYXJpc29uT3BlcmF0b3IsXG4gICAgdmFsdWU6IGFueSxcbiAgKTogdGhpcztcbiAgLy8gSEFWSU5HIOq1rO2YhFxuICBoYXZpbmcoLi4uY29uZGl0aW9uczogYW55W10pOiB0aGlzIHtcbiAgICBpZiAoY29uZGl0aW9ucy5sZW5ndGggPT09IDEpIHtcbiAgICAgIC8vIGhhdmluZyhcIkNPVU5UKCopID4gMTBcIilcbiAgICAgIHRoaXMua25leFF1ZXJ5LmhhdmluZyh0aGlzLmtuZXgucmF3KGNvbmRpdGlvbnNbMF0pKTtcbiAgICB9IGVsc2UgaWYgKGNvbmRpdGlvbnMubGVuZ3RoID09PSAzKSB7XG4gICAgICAvLyBoYXZpbmcoXCJjb3VudFwiLCBcIj5cIiwgMTApXG4gICAgICB0aGlzLmtuZXhRdWVyeS5oYXZpbmcoXG4gICAgICAgIHRoaXMua25leC5yYXcoY29uZGl0aW9uc1swXSksXG4gICAgICAgIGNvbmRpdGlvbnNbMV0sXG4gICAgICAgIHRoaXMua25leC5yYXcoY29uZGl0aW9uc1syXSksXG4gICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJJbnZhbGlkIGhhdmluZyBhcmd1bWVudHNcIik7XG4gICAgfVxuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLy8g7Iuk7ZaJIOuplOyEnOuTnOuTpCAtIHRoZW5hYmxlIOq1rO2YhFxuICB0aGVuPFRSZXN1bHQxID0gRXhwYW5kPFRSZXN1bHQ+W10sIFRSZXN1bHQyID0gbmV2ZXI+KFxuICAgIG9uZnVsZmlsbGVkPzogKCh2YWx1ZTogRXhwYW5kPFRSZXN1bHQ+W10pID0+IFRSZXN1bHQxIHwgUHJvbWlzZUxpa2U8VFJlc3VsdDE+KSB8IG51bGwsXG4gICAgb25yZWplY3RlZD86ICgocmVhc29uOiBhbnkpID0+IFRSZXN1bHQyIHwgUHJvbWlzZUxpa2U8VFJlc3VsdDI+KSB8IG51bGwsXG4gICk6IFByb21pc2U8VFJlc3VsdDEgfCBUUmVzdWx0Mj4ge1xuICAgIE5haXRlLnQoXCJwdXJpOmV4ZWN1dGVkLXF1ZXJ5XCIsIHRoaXMudG9RdWVyeSgpKTtcbiAgICByZXR1cm4gdGhpcy5rbmV4UXVlcnkudGhlbihvbmZ1bGZpbGxlZCBhcyBhbnksIG9ucmVqZWN0ZWQpO1xuICB9XG4gIGNhdGNoPFRSZXN1bHQyID0gbmV2ZXI+KFxuICAgIG9ucmVqZWN0ZWQ/OiAoKHJlYXNvbjogYW55KSA9PiBUUmVzdWx0MiB8IFByb21pc2VMaWtlPFRSZXN1bHQyPikgfCBudWxsLFxuICApOiBQcm9taXNlPFRSZXN1bHQgfCBUUmVzdWx0Mj4ge1xuICAgIHJldHVybiB0aGlzLmtuZXhRdWVyeS5jYXRjaChvbnJlamVjdGVkKTtcbiAgfVxuICBmaW5hbGx5KG9uZmluYWxseT86ICgoKSA9PiB2b2lkKSB8IG51bGwpOiBQcm9taXNlPFRSZXN1bHQ+IHtcbiAgICByZXR1cm4gdGhpcy5rbmV4UXVlcnkuZmluYWxseShvbmZpbmFsbHkpO1xuICB9XG5cbiAgLy8g7ZWY64KY66eMIOy/vOumrFxuICBmaXJzdCgpOiBSZXNvbHZlZFB1cmk8RXhwYW5kPFRSZXN1bHQ+LCBuZXZlcj4ge1xuICAgIHRoaXMua25leFF1ZXJ5LmZpcnN0KCk7XG4gICAgcmV0dXJuIG5ldyBSZXNvbHZlZFB1cmkodGhpcy5rbmV4UXVlcnksIHRoaXMua25leCk7XG4gIH1cblxuICAvLyDsv7zrpqztlZwg66CI7L2U65Oc7JeQ7IScIO2KueyglSDsu6zrn7zrp4wg7LaU7Lac7ZWcIOuwsOyXtCDrpqzthLRcbiAgcGx1Y2s8VENvbHVtbiBleHRlbmRzIGtleW9mIFRSZXN1bHQgfCBSZXN1bHRBdmFpbGFibGVDb2x1bW5zPFRUYWJsZXMsIFRSZXN1bHQ+PihcbiAgICBjb2x1bW46IFRDb2x1bW4sXG4gICk6IFJlc29sdmVkUHVyaTxcbiAgICBUQ29sdW1uIGV4dGVuZHMga2V5b2YgVFJlc3VsdFxuICAgICAgPyBUUmVzdWx0W1RDb2x1bW5dW11cbiAgICAgIDogRXh0cmFjdENvbHVtblR5cGU8VFRhYmxlcywgVENvbHVtbiAmIHN0cmluZz5bXSxcbiAgICBuZXZlclxuICA+IHtcbiAgICB0aGlzLmtuZXhRdWVyeS5wbHVjayhjb2x1bW4gYXMgc3RyaW5nKTtcbiAgICByZXR1cm4gbmV3IFJlc29sdmVkUHVyaSh0aGlzLmtuZXhRdWVyeSwgdGhpcy5rbmV4KTtcbiAgfVxuXG4gIC8vIElOU0VSVFxuICBpbnNlcnQoXG4gICAgZGF0YTogSW5zZXJ0RGF0YTxTaW5nbGVUYWJsZVZhbHVlPFRUYWJsZXM+PixcbiAgKTogUmVzb2x2ZWRQdXJpPEluc2VydFJlc3VsdCwgU2luZ2xlVGFibGVWYWx1ZTxUVGFibGVzPj4ge1xuICAgIHRoaXMua25leFF1ZXJ5Lmluc2VydChkYXRhKTtcbiAgICByZXR1cm4gbmV3IFJlc29sdmVkUHVyaSh0aGlzLmtuZXhRdWVyeSwgdGhpcy5rbmV4KTtcbiAgfVxuXG4gIC8vIFVQREFURVxuICB1cGRhdGUoZGF0YTogV2hlcmVDb25kaXRpb248VFRhYmxlcz4pOiBSZXNvbHZlZFB1cmk8bnVtYmVyLCBTaW5nbGVUYWJsZVZhbHVlPFRUYWJsZXM+PiB7XG4gICAgdGhpcy5rbmV4UXVlcnkudXBkYXRlKGRhdGEpO1xuICAgIHJldHVybiBuZXcgUmVzb2x2ZWRQdXJpKHRoaXMua25leFF1ZXJ5LCB0aGlzLmtuZXgpO1xuICB9XG5cbiAgLy8gSW5jcmVtZW50XG4gIGluY3JlbWVudDxUQ29sdW1uIGV4dGVuZHMgQXZhaWxhYmxlQ29sdW1uczxUVGFibGVzPj4oXG4gICAgY29sdW1uOiBUQ29sdW1uLFxuICAgIHZhbHVlOiBudW1iZXIsXG4gICk6IFJlc29sdmVkUHVyaTxudW1iZXIsIFNpbmdsZVRhYmxlVmFsdWU8VFRhYmxlcz4+IHtcbiAgICBpZiAodmFsdWUgPD0gMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiSW5jcmVtZW50IHZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIDBcIik7XG4gICAgfVxuICAgIHRoaXMua25leFF1ZXJ5LmluY3JlbWVudChjb2x1bW4sIHZhbHVlKTtcbiAgICByZXR1cm4gbmV3IFJlc29sdmVkUHVyaSh0aGlzLmtuZXhRdWVyeSwgdGhpcy5rbmV4KTtcbiAgfVxuICAvLyBEZWNyZW1lbnRcbiAgZGVjcmVtZW50PFRDb2x1bW4gZXh0ZW5kcyBBdmFpbGFibGVDb2x1bW5zPFRUYWJsZXM+PihcbiAgICBjb2x1bW46IFRDb2x1bW4sXG4gICAgdmFsdWU6IG51bWJlcixcbiAgKTogUmVzb2x2ZWRQdXJpPG51bWJlciwgU2luZ2xlVGFibGVWYWx1ZTxUVGFibGVzPj4ge1xuICAgIGlmICh2YWx1ZSA8PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJEZWNyZW1lbnQgdmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gMFwiKTtcbiAgICB9XG4gICAgdGhpcy5rbmV4UXVlcnkuZGVjcmVtZW50KGNvbHVtbiwgdmFsdWUpO1xuICAgIHJldHVybiBuZXcgUmVzb2x2ZWRQdXJpKHRoaXMua25leFF1ZXJ5LCB0aGlzLmtuZXgpO1xuICB9XG5cbiAgLy8gREVMRVRFXG4gIGRlbGV0ZSgpOiBSZXNvbHZlZFB1cmk8bnVtYmVyLCBTaW5nbGVUYWJsZVZhbHVlPFRUYWJsZXM+PiB7XG4gICAgdGhpcy5rbmV4UXVlcnkuZGVsZXRlKCk7XG4gICAgcmV0dXJuIG5ldyBSZXNvbHZlZFB1cmkodGhpcy5rbmV4UXVlcnksIHRoaXMua25leCk7XG4gIH1cblxuICAvLyDtmZXsnbgg7L+866asIOumrO2EtFxuICB0b1F1ZXJ5KCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMua25leFF1ZXJ5LnRvUXVlcnkoKTtcbiAgfVxuXG4gIC8vIOy/vOumrCDrlJTrsoTquYUg66Gc6re4IOy2nOugpVxuICBkZWJ1ZygpOiB0aGlzIHtcbiAgICBjb25zb2xlLmxvZyhgJHtjaGFsay5jeWFuKFwiW1B1cmkgRGVidWddXCIpfSAke2NoYWxrLnllbGxvdyh0aGlzLnRvUXVlcnkoKSl9YCk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBjbG9uZSgpOiBQdXJpPFRTY2hlbWEsIFRUYWJsZXMsIFRSZXN1bHQ+IHtcbiAgICAvLyAnZHVhbCfsnYAg642U66+4IO2FjOydtOu4lOydtOupsCwg67CU66GcIOyVhOuemCDspITsl5DshJwga25leFF1ZXJ56rCAIOuNruyWtOyUjOybjOynkeuLiOuLpC5cbiAgICBjb25zdCBuZXdQdXJpID0gbmV3IFB1cmk8VFNjaGVtYSwgVFRhYmxlcywgVFJlc3VsdD4odGhpcy5rbmV4LCBcImR1YWxcIik7XG4gICAgbmV3UHVyaS5rbmV4UXVlcnkgPSB0aGlzLmtuZXhRdWVyeS5jbG9uZSgpO1xuICAgIHJldHVybiBuZXdQdXJpO1xuICB9XG5cbiAgZm9ybWF0U1FMKHVuZm9ybWF0dGVkOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIC8vIFNRTCDsmIjslb3slrQg66qp66GdXG4gICAgY29uc3Qga2V5d29yZHMgPSBbXG4gICAgICBcIlNFTEVDVFwiLFxuICAgICAgXCJGUk9NXCIsXG4gICAgICBcIldIRVJFXCIsXG4gICAgICBcIklOU0VSVFwiLFxuICAgICAgXCJJTlRPXCIsXG4gICAgICBcIlZBTFVFU1wiLFxuICAgICAgXCJVUERBVEVcIixcbiAgICAgIFwiREVMRVRFXCIsXG4gICAgICBcIkNSRUFURVwiLFxuICAgICAgXCJUQUJMRVwiLFxuICAgICAgXCJBTFRFUlwiLFxuICAgICAgXCJEUk9QXCIsXG4gICAgICBcIkpPSU5cIixcbiAgICAgIFwiT05cIixcbiAgICAgIFwiSU5ORVJcIixcbiAgICAgIFwiTEVGVFwiLFxuICAgICAgXCJSSUdIVFwiLFxuICAgICAgXCJGVUxMXCIsXG4gICAgICBcIk9VVEVSXCIsXG4gICAgICBcIkdST1VQXCIsXG4gICAgICBcIkJZXCIsXG4gICAgICBcIk9SREVSXCIsXG4gICAgICBcIkhBVklOR1wiLFxuICAgICAgXCJESVNUSU5DVFwiLFxuICAgICAgXCJMSU1JVFwiLFxuICAgICAgXCJPRkZTRVRcIixcbiAgICAgIFwiQVNcIixcbiAgICAgIFwiQU5EXCIsXG4gICAgICBcIk9SXCIsXG4gICAgICBcIk5PVFwiLFxuICAgICAgXCJJTlwiLFxuICAgICAgXCJMSUtFXCIsXG4gICAgICBcIklTXCIsXG4gICAgICBcIk5VTExcIixcbiAgICAgIFwiQ0FTRVwiLFxuICAgICAgXCJXSEVOXCIsXG4gICAgICBcIlRIRU5cIixcbiAgICAgIFwiRUxTRVwiLFxuICAgICAgXCJFTkRcIixcbiAgICAgIFwiVU5JT05cIixcbiAgICAgIFwiQUxMXCIsXG4gICAgICBcIkVYSVNUU1wiLFxuICAgICAgXCJCRVRXRUVOXCIsXG4gICAgXTtcblxuICAgIGxldCBmb3JtYXR0ZWQgPSB1bmZvcm1hdHRlZDtcblxuICAgIC8vIOyYiOyVveyWtOulvCDrjIDrrLjsnpDroZwg67OA7ZmYXG4gICAga2V5d29yZHMuZm9yRWFjaCgoa2V5d29yZCkgPT4ge1xuICAgICAgY29uc3QgcmVnZXggPSBuZXcgUmVnRXhwKGBcXFxcYiR7a2V5d29yZH1cXFxcYmAsIFwiZ2lcIik7XG4gICAgICBmb3JtYXR0ZWQgPSBmb3JtYXR0ZWQucmVwbGFjZShyZWdleCwga2V5d29yZC50b1VwcGVyQ2FzZSgpKTtcbiAgICB9KTtcblxuICAgIC8vIOyjvOyalCDsoIgg7JWe7JeQIOykhOuwlOq/iCDstpTqsIBcbiAgICBjb25zdCBtYWpvckNsYXVzZXMgPSBbXG4gICAgICBcIlNFTEVDVFwiLFxuICAgICAgXCJGUk9NXCIsXG4gICAgICBcIldIRVJFXCIsXG4gICAgICBcIkdST1VQIEJZXCIsXG4gICAgICBcIk9SREVSIEJZXCIsXG4gICAgICBcIkhBVklOR1wiLFxuICAgICAgXCJMSU1JVFwiLFxuICAgICAgXCJVTklPTlwiLFxuICAgIF07XG4gICAgbWFqb3JDbGF1c2VzLmZvckVhY2goKGNsYXVzZSkgPT4ge1xuICAgICAgY29uc3QgcmVnZXggPSBuZXcgUmVnRXhwKGBcXFxccysoJHtjbGF1c2V9KVxcXFxzK2AsIFwiZ2lcIik7XG4gICAgICBmb3JtYXR0ZWQgPSBmb3JtYXR0ZWQucmVwbGFjZShyZWdleCwgYFxcbiR7Y2xhdXNlLnRvVXBwZXJDYXNlKCl9IGApO1xuICAgIH0pO1xuXG4gICAgLy8gSk9JTiDsoIgg7LKY66asXG4gICAgZm9ybWF0dGVkID0gZm9ybWF0dGVkLnJlcGxhY2UoL1xccysoKD86SU5ORVJ8TEVGVHxSSUdIVHxGVUxMIE9VVEVSKVxccyspP0pPSU5cXHMrL2dpLCBcIlxcbiQxSk9JTiBcIik7XG5cbiAgICAvLyBBTkQsIE9SIOyhsOqxtCDsspjrpqxcbiAgICBmb3JtYXR0ZWQgPSBmb3JtYXR0ZWQucmVwbGFjZSgvXFxzKyhBTkR8T1IpXFxzKy9naSwgXCJcXG4gICQxIFwiKTtcblxuICAgIC8vIOq0hO2YuCDsspjrpqwg67CPIOuTpOyXrOyTsOq4sFxuICAgIGNvbnN0IGxpbmVzID0gZm9ybWF0dGVkLnNwbGl0KFwiXFxuXCIpO1xuICAgIGNvbnN0IGluZGVudGVkTGluZXMgPSBbXTtcbiAgICBsZXQgaW5kZW50TGV2ZWwgPSAwO1xuXG4gICAgZm9yIChjb25zdCBsaW5lIG9mIGxpbmVzKSB7XG4gICAgICBjb25zdCB0cmltbWVkTGluZSA9IGxpbmUudHJpbSgpO1xuICAgICAgaWYgKCF0cmltbWVkTGluZSkgY29udGludWU7XG5cbiAgICAgIC8vIOuLq+uKlCDqtITtmLjqsIAg7J6I7Jy866m0IOuTpOyXrOyTsOq4sCDroIjrsqgg6rCQ7IaMXG4gICAgICBjb25zdCBjbG9zaW5nUGFyZW5zID0gKHRyaW1tZWRMaW5lLm1hdGNoKC9cXCkvZykgfHwgW10pLmxlbmd0aDtcbiAgICAgIGNvbnN0IG9wZW5pbmdQYXJlbnMgPSAodHJpbW1lZExpbmUubWF0Y2goL1xcKC9nKSB8fCBbXSkubGVuZ3RoO1xuXG4gICAgICBpZiAoY2xvc2luZ1BhcmVucyA+IDAgJiYgb3BlbmluZ1BhcmVucyA9PT0gMCkge1xuICAgICAgICBpbmRlbnRMZXZlbCA9IE1hdGgubWF4KDAsIGluZGVudExldmVsIC0gY2xvc2luZ1BhcmVucyk7XG4gICAgICB9XG5cbiAgICAgIC8vIO2YhOyerCDrk6Tsl6zsk7DquLAg7KCB7JqpXG4gICAgICBjb25zdCBpbmRlbnQgPSBcIiAgXCIucmVwZWF0KGluZGVudExldmVsKTtcbiAgICAgIGluZGVudGVkTGluZXMucHVzaChpbmRlbnQgKyB0cmltbWVkTGluZSk7XG5cbiAgICAgIC8vIOyXrOuKlCDqtITtmLjqsIAg7J6I7Jy866m0IOuTpOyXrOyTsOq4sCDroIjrsqgg7Kad6rCAXG4gICAgICBpZiAob3BlbmluZ1BhcmVucyA+IGNsb3NpbmdQYXJlbnMpIHtcbiAgICAgICAgaW5kZW50TGV2ZWwgKz0gb3BlbmluZ1BhcmVucyAtIGNsb3NpbmdQYXJlbnM7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGluZGVudGVkTGluZXMuam9pbihcIlxcblwiKS50cmltKCk7XG4gIH1cblxuICAvLyBLbmV4IOy/vOumrCDruYzrjZQg7KeB7KCRIOygkeq3vFxuICByYXcoKTogS25leC5RdWVyeUJ1aWxkZXIge1xuICAgIHJldHVybiB0aGlzLmtuZXhRdWVyeTtcbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgV2hlcmVHcm91cDxUVGFibGVzIGV4dGVuZHMgUmVjb3JkPHN0cmluZywgYW55Pj4ge1xuICBjb25zdHJ1Y3Rvcihwcml2YXRlIGJ1aWxkZXI6IEtuZXguUXVlcnlCdWlsZGVyKSB7fVxuXG4gIC8vIHdoZXJlIOuplOyEnOuTnOuTpFxuICB3aGVyZShjb25kaXRpb25zOiBXaGVyZUNvbmRpdGlvbjxUVGFibGVzPik6IHRoaXM7XG4gIHdoZXJlPFRDb2x1bW4gZXh0ZW5kcyBBdmFpbGFibGVDb2x1bW5zPFRUYWJsZXM+PihcbiAgICBjb2x1bW46IFRDb2x1bW4sXG4gICAgdmFsdWU6IEV4dHJhY3RDb2x1bW5UeXBlPFRUYWJsZXMsIFRDb2x1bW4gJiBzdHJpbmc+LFxuICApOiB0aGlzO1xuICB3aGVyZTxUQ29sdW1uIGV4dGVuZHMgQXZhaWxhYmxlQ29sdW1uczxUVGFibGVzPj4oXG4gICAgY29sdW1uOiBUQ29sdW1uLFxuICAgIG9wZXJhdG9yOiBDb21wYXJpc29uT3BlcmF0b3IsXG4gICAgdmFsdWU6IEV4dHJhY3RDb2x1bW5UeXBlPFRUYWJsZXMsIFRDb2x1bW4gJiBzdHJpbmc+LFxuICApOiB0aGlzO1xuICB3aGVyZSguLi5hcmdzOiBhbnlbXSk6IFdoZXJlR3JvdXA8VFRhYmxlcz4ge1xuICAgIHRoaXMuYnVpbGRlci53aGVyZShhcmdzWzBdLCAuLi5hcmdzLnNsaWNlKDEpKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8vIG9yV2hlcmUg66mU7ISc65Oc65OkXG4gIG9yV2hlcmUoY29uZGl0aW9uczogV2hlcmVDb25kaXRpb248VFRhYmxlcz4pOiB0aGlzO1xuICBvcldoZXJlPFRDb2x1bW4gZXh0ZW5kcyBBdmFpbGFibGVDb2x1bW5zPFRUYWJsZXM+PihcbiAgICBjb2x1bW46IFRDb2x1bW4sXG4gICAgdmFsdWU6IEV4dHJhY3RDb2x1bW5UeXBlPFRUYWJsZXMsIFRDb2x1bW4gJiBzdHJpbmc+LFxuICApOiB0aGlzO1xuICBvcldoZXJlPFRDb2x1bW4gZXh0ZW5kcyBBdmFpbGFibGVDb2x1bW5zPFRUYWJsZXM+PihcbiAgICBjb2x1bW46IFRDb2x1bW4sXG4gICAgb3BlcmF0b3I6IENvbXBhcmlzb25PcGVyYXRvcixcbiAgICB2YWx1ZTogRXh0cmFjdENvbHVtblR5cGU8VFRhYmxlcywgVENvbHVtbiAmIHN0cmluZz4sXG4gICk6IHRoaXM7XG4gIG9yV2hlcmUoLi4uYXJnczogYW55W10pOiBXaGVyZUdyb3VwPFRUYWJsZXM+IHtcbiAgICB0aGlzLmJ1aWxkZXIub3JXaGVyZShhcmdzWzBdLCAuLi5hcmdzLnNsaWNlKDEpKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8vIOykkeyyqSDqt7jro7lcbiAgd2hlcmVHcm91cChjYWxsYmFjazogKGc6IFdoZXJlR3JvdXA8VFRhYmxlcz4pID0+IHZvaWQpOiB0aGlzO1xuICB3aGVyZUdyb3VwKGNhbGxiYWNrOiAoZzogV2hlcmVHcm91cDxUVGFibGVzPikgPT4gdm9pZCk6IFdoZXJlR3JvdXA8VFRhYmxlcz4ge1xuICAgIHRoaXMuYnVpbGRlci53aGVyZSgoc3ViQnVpbGRlcikgPT4ge1xuICAgICAgY29uc3Qgc3ViR3JvdXAgPSBuZXcgV2hlcmVHcm91cDxUVGFibGVzPihzdWJCdWlsZGVyKTtcbiAgICAgIGNhbGxiYWNrKHN1Ykdyb3VwKTtcbiAgICB9KTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuICBvcldoZXJlR3JvdXAoY2FsbGJhY2s6IChnOiBXaGVyZUdyb3VwPFRUYWJsZXM+KSA9PiB2b2lkKTogdGhpcztcbiAgb3JXaGVyZUdyb3VwKGNhbGxiYWNrOiAoZzogV2hlcmVHcm91cDxUVGFibGVzPikgPT4gdm9pZCk6IFdoZXJlR3JvdXA8VFRhYmxlcz4ge1xuICAgIHRoaXMuYnVpbGRlci5vcldoZXJlKChzdWJCdWlsZGVyKSA9PiB7XG4gICAgICBjb25zdCBzdWJHcm91cCA9IG5ldyBXaGVyZUdyb3VwPFRUYWJsZXM+KHN1YkJ1aWxkZXIpO1xuICAgICAgY2FsbGJhY2soc3ViR3JvdXApO1xuICAgIH0pO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBKb2luQ2xhdXNlR3JvdXA8XG4gIFRMZWZ0IGV4dGVuZHMgUmVjb3JkPHN0cmluZywgYW55PixcbiAgVFJpZ2h0IGV4dGVuZHMgUmVjb3JkPHN0cmluZywgYW55Pixcbj4ge1xuICBjb25zdHJ1Y3Rvcihwcml2YXRlIGNhbGxiYWNrOiBLbmV4LkpvaW5DbGF1c2UpIHt9XG5cbiAgLy8gT04oQU5EKTog7Lus65+8ID0g7Lus65+8XG4gIG9uKGxlZnQ6IEF2YWlsYWJsZUNvbHVtbnM8VExlZnQ+LCByaWdodDogQXZhaWxhYmxlQ29sdW1uczxUUmlnaHQ+KTogdGhpcztcbiAgLy8gT04oQU5EKTog7Lus65+8ICjsl7DsgrDsnpApIOy7rOufvFxuICBvbihcbiAgICBsZWZ0OiBBdmFpbGFibGVDb2x1bW5zPFRMZWZ0PixcbiAgICBvcGVyYXRvcjogQ29tcGFyaXNvbk9wZXJhdG9yLFxuICAgIHJpZ2h0OiBBdmFpbGFibGVDb2x1bW5zPFRSaWdodD4sXG4gICk6IHRoaXM7XG4gIC8vIE9OKEFORCk6IOy9nOuwsVxuICBvbihjYWxsYmFjazogKG5lc3RlZDogSm9pbkNsYXVzZUdyb3VwPFRMZWZ0LCBUUmlnaHQ+KSA9PiB2b2lkKTogdGhpcztcbiAgLy8gT04oQU5EKSDqtaztmIRcbiAgb24oLi4uYXJnczogYW55W10pOiB0aGlzIHtcbiAgICB0aGlzLmNhbGxiYWNrLm9uKC4uLihhcmdzIGFzIFtzdHJpbmcsIHN0cmluZ10pKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8vIE9OKE9SKTog7Lus65+8ID0g7Lus65+8XG4gIG9yT24obGVmdDogQXZhaWxhYmxlQ29sdW1uczxUTGVmdD4sIHJpZ2h0OiBBdmFpbGFibGVDb2x1bW5zPFRSaWdodD4pOiB0aGlzO1xuICAvLyBPTihPUik6IOy7rOufvCAo7Jew7IKw7J6QKSDsu6zrn7xcbiAgb3JPbihcbiAgICBsZWZ0OiBBdmFpbGFibGVDb2x1bW5zPFRMZWZ0PixcbiAgICBvcGVyYXRvcjogQ29tcGFyaXNvbk9wZXJhdG9yLFxuICAgIHJpZ2h0OiBBdmFpbGFibGVDb2x1bW5zPFRSaWdodD4sXG4gICk6IHRoaXM7XG4gIC8vIE9OKE9SKTog7L2c67CxXG4gIG9yT24oY2FsbGJhY2s6IChuZXN0ZWQ6IEpvaW5DbGF1c2VHcm91cDxUTGVmdCwgVFJpZ2h0PikgPT4gdm9pZCk6IHRoaXM7XG4gIC8vIE9OKE9SKSDqtaztmIRcbiAgb3JPbiguLi5hcmdzOiBhbnlbXSk6IHRoaXMge1xuICAgIHRoaXMuY2FsbGJhY2sub3JPbiguLi4oYXJncyBhcyBbc3RyaW5nLCBzdHJpbmddKSk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cbn1cblxuLypcbiAgVFJlc29sdmVkOiDsv7zrpqwg7Iuk7ZaJIO2bhCDrsJjtmZjrkKAg6rKw6rO8IO2DgOyehVxuICBUUmV0dXJuaW5nOiBSRVRVUk5JTkcg7KCI7JeQIOyCrOyaqeuQoCDtg4DsnoVcbiovXG5leHBvcnQgY2xhc3MgUmVzb2x2ZWRQdXJpPFRSZXNvbHZlZCwgVFJldHVybmluZz4ge1xuICBjb25zdHJ1Y3RvcihcbiAgICBwdWJsaWMga25leFF1ZXJ5OiBLbmV4LlF1ZXJ5QnVpbGRlcixcbiAgICBwcml2YXRlIGtuZXg6IEtuZXgsXG4gICkge31cblxuICB0b1F1ZXJ5KCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMua25leFF1ZXJ5LnRvUXVlcnkoKTtcbiAgfVxuXG4gIGRlYnVnKCk6IHRoaXMge1xuICAgIGNvbnNvbGUubG9nKGAke2NoYWxrLmN5YW4oXCJbUHVyaSBEZWJ1Z11cIil9ICR7Y2hhbGsueWVsbG93KHRoaXMudG9RdWVyeSgpKX1gKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIHRoZW48VFJlc3VsdDEgPSBUUmVzb2x2ZWQsIFRSZXN1bHQyID0gbmV2ZXI+KFxuICAgIG9uZnVsZmlsbGVkPzogKCh2YWx1ZTogVFJlc29sdmVkKSA9PiBUUmVzdWx0MSB8IFByb21pc2VMaWtlPFRSZXN1bHQxPikgfCBudWxsLFxuICAgIG9ucmVqZWN0ZWQ/OiAoKHJlYXNvbjogYW55KSA9PiBUUmVzdWx0MiB8IFByb21pc2VMaWtlPFRSZXN1bHQyPikgfCBudWxsLFxuICApOiBQcm9taXNlPFRSZXN1bHQxIHwgVFJlc3VsdDI+IHtcbiAgICBOYWl0ZS50KFwicHVyaTpleGVjdXRlZC1xdWVyeVwiLCB0aGlzLnRvUXVlcnkoKSk7XG4gICAgcmV0dXJuIHRoaXMua25leFF1ZXJ5LnRoZW4ob25mdWxmaWxsZWQgYXMgYW55LCBvbnJlamVjdGVkKTtcbiAgfVxuICBjYXRjaDxUUmVzdWx0MiA9IG5ldmVyPihcbiAgICBvbnJlamVjdGVkPzogKChyZWFzb246IGFueSkgPT4gVFJlc3VsdDIgfCBQcm9taXNlTGlrZTxUUmVzdWx0Mj4pIHwgbnVsbCxcbiAgKTogUHJvbWlzZTxUUmVzb2x2ZWQgfCBUUmVzdWx0Mj4ge1xuICAgIHJldHVybiB0aGlzLmtuZXhRdWVyeS5jYXRjaChvbnJlamVjdGVkKTtcbiAgfVxuICBmaW5hbGx5KG9uZmluYWxseT86ICgoKSA9PiB2b2lkKSB8IG51bGwpOiBQcm9taXNlPFRSZXNvbHZlZD4ge1xuICAgIHJldHVybiB0aGlzLmtuZXhRdWVyeS5maW5hbGx5KG9uZmluYWxseSk7XG4gIH1cblxuICAvLyBPTiBDT05GTElDVCAtIOy7rOufvCDquLDrsJhcbiAgb25Db25mbGljdDxUVGFibGVzIGV4dGVuZHMgUmVjb3JkPHN0cmluZywgVFJldHVybmluZz4+KFxuICAgIGNvbHVtbnM6IHN0cmluZyB8IHN0cmluZ1tdLFxuICAgIGFjdGlvbj86IE9uQ29uZmxpY3RBY3Rpb248VFRhYmxlcz4sXG4gICk6IHRoaXMge1xuICAgIGNvbnN0IHRhcmdldCA9IEFycmF5LmlzQXJyYXkoY29sdW1ucykgPyBjb2x1bW5zIDogW2NvbHVtbnNdO1xuXG4gICAgaWYgKCFhY3Rpb24gfHwgYWN0aW9uID09PSBcIm5vdGhpbmdcIikge1xuICAgICAgLy8gRE8gTk9USElOR1xuICAgICAgdGhpcy5rbmV4UXVlcnkub25Db25mbGljdCh0YXJnZXQpLmlnbm9yZSgpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBETyBVUERBVEVcbiAgICAgIGNvbnN0IHsgdXBkYXRlIH0gPSBhY3Rpb247XG5cbiAgICAgIC8vIGFjdGlvbi51cGRhdGUg67Cw7Je0IO2Yle2DnCA6IFtcIm5hbWVcIiwgXCJlbWFpbFwiXVxuICAgICAgaWYgKEFycmF5LmlzQXJyYXkodXBkYXRlKSkge1xuICAgICAgICB0aGlzLmtuZXhRdWVyeS5vbkNvbmZsaWN0KHRhcmdldCkubWVyZ2UodXBkYXRlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIGFjdGlvbi51cGRhdGUg6rCd7LK0IO2Yle2DnDogeyBuYW1lOiBcIkpvaG5cIiwgY291bnQ6IHJhdyguLi4pIH1cbiAgICAgICAgY29uc3QgbWVyZ2VPYmo6IFJlY29yZDxzdHJpbmcsIGFueT4gPSB7fTtcblxuICAgICAgICBmb3IgKGNvbnN0IFtrZXksIHZhbHVlXSBvZiBPYmplY3QuZW50cmllcyh1cGRhdGUpKSB7XG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgdmFsdWUgJiZcbiAgICAgICAgICAgIHR5cGVvZiB2YWx1ZSA9PT0gXCJvYmplY3RcIiAmJlxuICAgICAgICAgICAgXCJfdHlwZVwiIGluIHZhbHVlICYmXG4gICAgICAgICAgICB2YWx1ZS5fdHlwZSA9PT0gXCJzcWxfZXhwcmVzc2lvblwiXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICAvLyBTcWxFeHByZXNzaW9uIOKGkiBrbmV4LnJhdygp66GcIOuzgO2ZmFxuICAgICAgICAgICAgbWVyZ2VPYmpba2V5XSA9IHRoaXMua25leC5yYXcoKHZhbHVlIGFzIFNxbEV4cHJlc3Npb248YW55PikuX3NxbCk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIOydvOuwmCDqsJJcbiAgICAgICAgICAgIG1lcmdlT2JqW2tleV0gPSB2YWx1ZTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmtuZXhRdWVyeS5vbkNvbmZsaWN0KHRhcmdldCkubWVyZ2UobWVyZ2VPYmopO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLy8gUkVUVVJOSU5HOiBcIipcIiAtIOyghOyytCDsu6zrn7xcbiAgcmV0dXJuaW5nKGNvbHVtbjogXCIqXCIpOiBSZXNvbHZlZFB1cmk8VFJldHVybmluZ1tdLCBuZXZlcj47XG4gIC8vIFJFVFVSTklORzog64uo7J28IOy7rOufvFxuICByZXR1cm5pbmc8VENvbHVtbiBleHRlbmRzIENvbHVtbktleXM8VFJldHVybmluZz4+KFxuICAgIGNvbHVtbjogVENvbHVtbixcbiAgKTogUmVzb2x2ZWRQdXJpPFBpY2s8VFJldHVybmluZywgVENvbHVtbj5bXSwgbmV2ZXI+O1xuICAvLyBSRVRVUk5JTkc6IOuzteyImCDsu6zrn7wgKOuwsOyXtClcbiAgcmV0dXJuaW5nPFRDb2x1bW4gZXh0ZW5kcyBDb2x1bW5LZXlzPFRSZXR1cm5pbmc+PihcbiAgICBjb2x1bW5zOiBUQ29sdW1uW10sXG4gICk6IFJlc29sdmVkUHVyaTxQaWNrPFRSZXR1cm5pbmcsIFRDb2x1bW4+W10sIG5ldmVyPjtcbiAgLy8gUkVUVVJOSU5HIOq1rO2YhFxuICByZXR1cm5pbmcoY29sdW1uT3JDb2x1bW5zOiBzdHJpbmcgfCBzdHJpbmdbXSk6IFJlc29sdmVkUHVyaTxhbnlbXSwgbmV2ZXI+IHtcbiAgICB0aGlzLmtuZXhRdWVyeS5yZXR1cm5pbmcoY29sdW1uT3JDb2x1bW5zKTtcbiAgICByZXR1cm4gbmV3IFJlc29sdmVkUHVyaSh0aGlzLmtuZXhRdWVyeSwgdGhpcy5rbmV4KTtcbiAgfVxufVxuIl0sIm5hbWVzIjpbImFzc2VydCIsImNoYWxrIiwiTmFpdGUiLCJQdXJpIiwia25leFF1ZXJ5Iiwia25leCIsInRhYmxlTmFtZU9yU3BlYyIsImZyb20iLCJlbnRyaWVzIiwiT2JqZWN0IiwibGVuZ3RoIiwiRXJyb3IiLCJhbGlhcyIsInNwZWMiLCJzdWJxdWVyeUJ1aWxkZXIiLCJyYXciLCJhcyIsImNvdW50IiwiY29sdW1uIiwiX3R5cGUiLCJfcmV0dXJuIiwiX3NxbCIsInN1bSIsImF2ZyIsIm1heCIsIm1pbiIsImNvbmNhdCIsImFyZ3MiLCJqb2luIiwidXBwZXIiLCJsb3dlciIsInJhd1N0cmluZyIsInNxbCIsInJhd051bWJlciIsInJhd0Jvb2xlYW4iLCJyYXdEYXRlIiwic2VsZWN0Iiwic2VsZWN0T2JqIiwic2VsZWN0Q2xhdXNlcyIsImNvbHVtbk9yRnVuY3Rpb24iLCJwdXNoIiwiY29sdW1uUGF0aCIsImFwcGVuZFNlbGVjdCIsInNlbGVjdEFsbCIsImNsZWFyIiwic3RhdGVtZW50IiwiY2xlYXJKb2luIiwiX3N0YXRlbWVudHMiLCJmaWx0ZXIiLCJzIiwiX2FsaWFzIiwiX3RhYmxlIiwidGFibGUiLCJfX2NvbW1vbkpvaW4iLCJsZWZ0Sm9pbiIsImpvaW5UeXBlIiwidGFibGVOYW1lIiwiY2FsbGJhY2siLCJqb2luQ2xhdXNlIiwiSm9pbkNsYXVzZUdyb3VwIiwibGVmdCIsInJpZ2h0Iiwid2hlcmUiLCJjb2x1bW5PckNvbmRpdGlvbnMiLCJvcGVyYXRvck9yVmFsdWUiLCJ2YWx1ZSIsIndoZXJlTnVsbCIsIndoZXJlTm90TnVsbCIsIndoZXJlSW4iLCJ2YWx1ZXMiLCJ3aGVyZU5vdEluIiwid2hlcmVNYXRjaCIsIndoZXJlUmF3IiwiU3RyaW5nIiwid2hlcmVHcm91cCIsImJ1aWxkZXIiLCJncm91cCIsIldoZXJlR3JvdXAiLCJvcldoZXJlR3JvdXAiLCJvcldoZXJlIiwib3JkZXJCeSIsImRpcmVjdGlvbiIsImxpbWl0Iiwib2Zmc2V0IiwiZ3JvdXBCeSIsImNvbHVtbnMiLCJoYXZpbmciLCJjb25kaXRpb25zIiwidGhlbiIsIm9uZnVsZmlsbGVkIiwib25yZWplY3RlZCIsInQiLCJ0b1F1ZXJ5IiwiY2F0Y2giLCJmaW5hbGx5Iiwib25maW5hbGx5IiwiZmlyc3QiLCJSZXNvbHZlZFB1cmkiLCJwbHVjayIsImluc2VydCIsImRhdGEiLCJ1cGRhdGUiLCJpbmNyZW1lbnQiLCJkZWNyZW1lbnQiLCJkZWxldGUiLCJkZWJ1ZyIsImNvbnNvbGUiLCJsb2ciLCJjeWFuIiwieWVsbG93IiwiY2xvbmUiLCJuZXdQdXJpIiwiZm9ybWF0U1FMIiwidW5mb3JtYXR0ZWQiLCJrZXl3b3JkcyIsImZvcm1hdHRlZCIsImZvckVhY2giLCJrZXl3b3JkIiwicmVnZXgiLCJSZWdFeHAiLCJyZXBsYWNlIiwidG9VcHBlckNhc2UiLCJtYWpvckNsYXVzZXMiLCJjbGF1c2UiLCJsaW5lcyIsInNwbGl0IiwiaW5kZW50ZWRMaW5lcyIsImluZGVudExldmVsIiwibGluZSIsInRyaW1tZWRMaW5lIiwidHJpbSIsImNsb3NpbmdQYXJlbnMiLCJtYXRjaCIsIm9wZW5pbmdQYXJlbnMiLCJNYXRoIiwiaW5kZW50IiwicmVwZWF0Iiwic2xpY2UiLCJzdWJCdWlsZGVyIiwic3ViR3JvdXAiLCJvbiIsIm9yT24iLCJvbkNvbmZsaWN0IiwiYWN0aW9uIiwidGFyZ2V0IiwiQXJyYXkiLCJpc0FycmF5IiwiaWdub3JlIiwibWVyZ2UiLCJtZXJnZU9iaiIsImtleSIsInJldHVybmluZyIsImNvbHVtbk9yQ29sdW1ucyJdLCJtYXBwaW5ncyI6IkFBQUEsc0ZBQXNGLEdBQ3RGLDZFQUE2RSxHQUU3RSxPQUFPQSxZQUFZLFNBQVM7QUFDNUIsT0FBT0MsV0FBVyxRQUFRO0FBRTFCLFNBQVNDLEtBQUssUUFBUSxvQkFBaUI7QUFvQnZDLE9BQU8sTUFBTUM7O0lBQ0hDLFVBQTZCO0lBS3JDLFlBQ0UsQUFBT0MsSUFBVSxFQUNqQkMsZUFBb0IsQ0FDcEI7YUFGT0QsT0FBQUE7UUFHUCxJQUFJLE9BQU9DLG9CQUFvQixVQUFVO1lBQ3ZDLGdDQUFnQztZQUNoQyxJQUFJLENBQUNGLFNBQVMsR0FBRyxJQUFJLENBQUNDLElBQUksQ0FBQ0MsaUJBQWlCQyxJQUFJLENBQUNEO1FBQ25ELE9BQU8sSUFBSSxPQUFPQSxvQkFBb0IsVUFBVTtZQUM5QyxNQUFNRSxVQUFVQyxPQUFPRCxPQUFPLENBQUNGO1lBQy9CLElBQUlFLFFBQVFFLE1BQU0sS0FBSyxHQUFHO2dCQUN4QixNQUFNLElBQUlDLE1BQU07WUFDbEI7WUFDQVgsT0FBT1EsT0FBTyxDQUFDLEVBQUU7WUFDakIsTUFBTSxDQUFDSSxPQUFPQyxLQUFLLEdBQUdMLE9BQU8sQ0FBQyxFQUFFO1lBQ2hDLElB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
|