sonamu 0.5.7 → 0.6.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/dist/api/base-frame.js +12 -2
- package/dist/api/caster.js +66 -2
- package/dist/api/code-converters.js +489 -2
- package/dist/api/config.d.ts +76 -0
- package/dist/api/config.d.ts.map +1 -0
- package/dist/api/config.js +32 -0
- package/dist/api/context.d.ts +1 -0
- package/dist/api/context.d.ts.map +1 -1
- package/dist/api/context.js +3 -2
- package/dist/api/decorators.d.ts.map +1 -1
- package/dist/api/decorators.js +142 -2
- package/dist/api/index.js +9 -2
- package/dist/api/sonamu.d.ts +8 -22
- package/dist/api/sonamu.d.ts.map +1 -1
- package/dist/api/sonamu.js +482 -2
- package/dist/bin/build-config.d.ts +2 -1
- package/dist/bin/build-config.d.ts.map +1 -1
- package/dist/bin/build-config.js +12 -2
- package/dist/bin/cli-wrapper.js +71 -2
- package/dist/bin/cli.js +418 -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/database/_batch_update.js +78 -2
- package/dist/database/base-model.js +247 -2
- package/dist/database/code-generator.js +53 -2
- package/dist/database/db.d.ts +2 -16
- package/dist/database/db.d.ts.map +1 -1
- package/dist/database/db.js +132 -2
- package/dist/database/knex-plugins/knex-on-duplicate-update.js +39 -2
- package/dist/database/puri-wrapper.js +109 -2
- package/dist/database/puri.d.ts +23 -16
- package/dist/database/puri.d.ts.map +1 -1
- package/dist/database/puri.js +539 -2
- package/dist/database/puri.types.d.ts +8 -3
- package/dist/database/puri.types.d.ts.map +1 -1
- package/dist/database/puri.types.js +3 -2
- package/dist/database/transaction-context.js +14 -2
- package/dist/database/upsert-builder.js +215 -2
- package/dist/entity/entity-manager.d.ts +3 -1
- package/dist/entity/entity-manager.d.ts.map +1 -1
- package/dist/entity/entity-manager.js +114 -2
- package/dist/entity/entity-utils.js +210 -2
- package/dist/entity/entity.d.ts.map +1 -1
- package/dist/entity/entity.js +651 -2
- package/dist/exceptions/error-handler.js +29 -2
- package/dist/exceptions/so-exceptions.js +85 -2
- package/dist/file-storage/driver.js +79 -2
- package/dist/file-storage/file-storage.js +75 -2
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +28 -2
- package/dist/migration/code-generation.js +558 -2
- package/dist/migration/migration-set.js +364 -2
- package/dist/migration/migrator.d.ts +0 -9
- package/dist/migration/migrator.d.ts.map +1 -1
- package/dist/migration/migrator.js +510 -2
- package/dist/migration/types.js +3 -2
- package/dist/naite/naite.d.ts +12 -0
- package/dist/naite/naite.d.ts.map +1 -0
- package/dist/naite/naite.js +72 -0
- package/dist/stream/index.js +3 -2
- package/dist/stream/sse.js +38 -2
- package/dist/syncer/api-parser.d.ts +20 -0
- package/dist/syncer/api-parser.d.ts.map +1 -0
- package/dist/syncer/api-parser.js +229 -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 +141 -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 +58 -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 +82 -0
- package/dist/syncer/syncer.d.ts +93 -108
- package/dist/syncer/syncer.d.ts.map +1 -1
- package/dist/syncer/syncer.js +375 -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 +101 -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 +87 -0
- package/dist/{templates → template/implementations}/generated.template.d.ts +3 -3
- package/dist/template/implementations/generated.template.d.ts.map +1 -0
- package/dist/template/implementations/generated.template.js +232 -0
- package/dist/{templates → template/implementations}/generated_http.template.d.ts +3 -3
- 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 +3 -3
- package/dist/template/implementations/generated_sso.template.d.ts.map +1 -0
- package/dist/template/implementations/generated_sso.template.js +105 -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 +171 -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 +193 -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 +465 -0
- package/dist/{templates → template/implementations}/view_list_columns.template.d.ts +3 -3
- 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 +5 -0
- package/dist/template/index.d.ts.map +1 -0
- package/dist/template/index.js +6 -0
- package/dist/template/template.d.ts +39 -0
- package/dist/template/template.d.ts.map +1 -0
- package/dist/template/template.js +47 -0
- package/dist/template/zod-converter.d.ts +18 -0
- package/dist/template/zod-converter.d.ts.map +1 -0
- package/dist/template/zod-converter.js +166 -0
- package/dist/testing/_relation-graph.js +80 -2
- package/dist/testing/fixture-manager.d.ts.map +1 -1
- package/dist/testing/fixture-manager.js +521 -2
- package/dist/types/types.d.ts +39 -40
- package/dist/types/types.d.ts.map +1 -1
- package/dist/types/types.js +289 -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.js +26 -2
- package/dist/utils/esm-utils.d.ts +45 -0
- package/dist/utils/esm-utils.d.ts.map +1 -0
- package/dist/utils/esm-utils.js +56 -0
- package/dist/utils/fs-utils.js +17 -2
- package/dist/utils/lodash-able.js +6 -2
- package/dist/utils/model.js +22 -2
- 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.js +35 -2
- package/dist/utils/utils.d.ts +4 -7
- package/dist/utils/utils.d.ts.map +1 -1
- package/dist/utils/utils.js +33 -2
- package/dist/utils/zod-error.d.ts.map +1 -1
- package/dist/utils/zod-error.js +19 -2
- package/package.json +21 -8
- package/src/api/code-converters.ts +2 -2
- package/src/api/config.ts +142 -0
- package/src/api/context.ts +1 -0
- package/src/api/decorators.ts +1 -0
- package/src/api/sonamu.ts +81 -67
- package/src/bin/build-config.ts +2 -1
- package/src/bin/cli-wrapper.ts +10 -3
- package/src/bin/cli.ts +108 -56
- package/src/bin/hot-hook-register.ts +22 -0
- package/src/database/base-model.ts +1 -1
- package/src/database/code-generator.ts +1 -1
- package/src/database/db.ts +10 -52
- package/src/database/puri.ts +78 -53
- package/src/database/puri.types.ts +18 -5
- package/src/database/upsert-builder.ts +1 -1
- package/src/entity/entity-manager.ts +19 -15
- package/src/entity/entity.ts +4 -3
- package/src/index.ts +2 -0
- package/src/migration/code-generation.ts +1 -1
- package/src/migration/migration-set.ts +1 -1
- package/src/migration/migrator.ts +23 -152
- package/src/naite/naite.ts +70 -0
- package/src/syncer/api-parser.ts +299 -0
- package/src/syncer/checksum.ts +152 -0
- package/src/syncer/code-generator.ts +202 -0
- package/src/syncer/entity-operations.ts +68 -0
- package/src/syncer/file-patterns.ts +56 -0
- package/src/syncer/index.ts +6 -0
- package/src/syncer/module-loader.ts +125 -0
- package/src/syncer/syncer.ts +363 -1420
- package/src/template/entity-converter.ts +123 -0
- package/src/template/helpers.ts +84 -0
- package/src/{templates → template/implementations}/entity.template.ts +4 -4
- package/src/{templates → template/implementations}/generated.template.ts +9 -9
- package/src/{templates → template/implementations}/generated_http.template.ts +9 -6
- package/src/{templates → template/implementations}/generated_sso.template.ts +7 -7
- package/src/{templates → template/implementations}/init_types.template.ts +4 -4
- package/src/{templates → template/implementations}/model.template.ts +9 -9
- package/src/{templates → template/implementations}/model_test.template.ts +5 -5
- package/src/{templates → template/implementations}/service.template.ts +19 -11
- package/src/{templates → template/implementations}/view_enums_buttonset.template.ts +3 -3
- package/src/{templates → template/implementations}/view_enums_dropdown.template.ts +5 -21
- package/src/{templates → template/implementations}/view_enums_select.template.ts +4 -4
- package/src/{templates → template/implementations}/view_form.template.ts +11 -13
- package/src/{templates → template/implementations}/view_id_all_select.template.ts +3 -3
- package/src/{templates → template/implementations}/view_id_async_select.template.ts +3 -3
- package/src/{templates → template/implementations}/view_list.template.ts +13 -64
- package/src/{templates → template/implementations}/view_list_columns.template.ts +3 -3
- package/src/{templates → template/implementations}/view_search_input.template.ts +3 -3
- package/src/template/index.ts +4 -0
- package/src/template/template.ts +86 -0
- package/src/template/zod-converter.ts +219 -0
- package/src/testing/fixture-manager.ts +8 -1
- package/src/types/types.ts +38 -61
- package/src/utils/async-utils.ts +17 -0
- package/src/utils/console-util.ts +4 -0
- package/src/utils/esm-utils.ts +69 -0
- package/src/utils/path-utils.ts +102 -0
- package/src/utils/process-utils.ts +46 -0
- package/src/utils/sql-parser.ts +1 -1
- package/src/utils/utils.ts +14 -40
- package/src/utils/zod-error.ts +0 -1
- 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.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.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.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.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/templates/base-template.ts +0 -19
- package/src/templates/index.ts +0 -1
package/dist/database/puri.js
CHANGED
|
@@ -1,2 +1,539 @@
|
|
|
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
|
+
import chalk from "chalk";
|
|
2
|
+
import assert from "assert";
|
|
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})`
|
|
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
|
+
// JOIN 실제 구현
|
|
151
|
+
join(tableNameOrSpec, ...args) {
|
|
152
|
+
return this.__commonJoin("join", tableNameOrSpec, ...args);
|
|
153
|
+
}
|
|
154
|
+
// LEFT JOIN 실제 구현
|
|
155
|
+
leftJoin(tableNameOrSpec, ...args) {
|
|
156
|
+
return this.__commonJoin("leftJoin", tableNameOrSpec, ...args);
|
|
157
|
+
}
|
|
158
|
+
__commonJoin(joinType, tableNameOrSpec, ...args) {
|
|
159
|
+
if (typeof tableNameOrSpec === "string") {
|
|
160
|
+
// Case 1: join("posts", ...)
|
|
161
|
+
const tableName = tableNameOrSpec;
|
|
162
|
+
if (args.length === 1 && typeof args[0] === "function") {
|
|
163
|
+
// join("posts", callback)
|
|
164
|
+
const callback = args[0];
|
|
165
|
+
this.knexQuery[joinType](tableName, (joinClause)=>{
|
|
166
|
+
callback(new JoinClauseGroup(joinClause));
|
|
167
|
+
});
|
|
168
|
+
} else {
|
|
169
|
+
// join("posts", left, right)
|
|
170
|
+
const [left, right] = args;
|
|
171
|
+
this.knexQuery[joinType](tableName, left, right);
|
|
172
|
+
}
|
|
173
|
+
} else if (typeof tableNameOrSpec === "object") {
|
|
174
|
+
// Case 2: join({ alias: "table" }, ...) or join({ alias: subquery }, ...)
|
|
175
|
+
const entries = Object.entries(tableNameOrSpec);
|
|
176
|
+
if (entries.length !== 1) {
|
|
177
|
+
throw new Error("Table spec must have exactly one entry");
|
|
178
|
+
}
|
|
179
|
+
assert(entries[0]);
|
|
180
|
+
const [[alias, spec]] = entries;
|
|
181
|
+
if (typeof spec === "string") {
|
|
182
|
+
// 테이블: join({ p: "posts" }, ...)
|
|
183
|
+
if (args.length === 1 && typeof args[0] === "function") {
|
|
184
|
+
// Callback
|
|
185
|
+
const callback = args[0];
|
|
186
|
+
this.knexQuery[joinType]({
|
|
187
|
+
[alias]: spec
|
|
188
|
+
}, (joinClause)=>{
|
|
189
|
+
callback(new JoinClauseGroup(joinClause));
|
|
190
|
+
});
|
|
191
|
+
} else {
|
|
192
|
+
// Simple
|
|
193
|
+
const [left, right] = args;
|
|
194
|
+
this.knexQuery[joinType]({
|
|
195
|
+
[alias]: spec
|
|
196
|
+
}, left, right);
|
|
197
|
+
}
|
|
198
|
+
} else if (spec instanceof Puri) {
|
|
199
|
+
// 서브쿼리: join({ sq: subquery }, ...)
|
|
200
|
+
if (args.length === 1 && typeof args[0] === "function") {
|
|
201
|
+
// Callback
|
|
202
|
+
const callback = args[0];
|
|
203
|
+
this.knexQuery[joinType](spec.raw().as(alias), (joinClause)=>{
|
|
204
|
+
callback(new JoinClauseGroup(joinClause));
|
|
205
|
+
});
|
|
206
|
+
} else {
|
|
207
|
+
// Simple
|
|
208
|
+
const [left, right] = args;
|
|
209
|
+
this.knexQuery[joinType](spec.raw().as(alias), left, right);
|
|
210
|
+
}
|
|
211
|
+
} else {
|
|
212
|
+
throw new Error("Invalid table specification");
|
|
213
|
+
}
|
|
214
|
+
} else {
|
|
215
|
+
throw new Error("Invalid arguments");
|
|
216
|
+
}
|
|
217
|
+
return this;
|
|
218
|
+
}
|
|
219
|
+
// WHERE: 컬럼 - 사용: .where("u.id", "like", "%test%")
|
|
220
|
+
where(columnOrConditions, operatorOrValue, value) {
|
|
221
|
+
if (typeof columnOrConditions === "object") {
|
|
222
|
+
this.knexQuery.where(columnOrConditions);
|
|
223
|
+
} else if (arguments.length === 2) {
|
|
224
|
+
if (operatorOrValue === null) {
|
|
225
|
+
this.knexQuery.whereNull(columnOrConditions);
|
|
226
|
+
return this;
|
|
227
|
+
}
|
|
228
|
+
this.knexQuery.where(columnOrConditions, operatorOrValue);
|
|
229
|
+
} else if (arguments.length === 3) {
|
|
230
|
+
if (value === null) {
|
|
231
|
+
if (operatorOrValue === "!=") {
|
|
232
|
+
this.knexQuery.whereNotNull(columnOrConditions);
|
|
233
|
+
return this;
|
|
234
|
+
} else if (operatorOrValue === "=") {
|
|
235
|
+
this.knexQuery.whereNull(columnOrConditions);
|
|
236
|
+
return this;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
this.knexQuery.where(columnOrConditions, operatorOrValue, value);
|
|
240
|
+
} else {
|
|
241
|
+
this.knexQuery.where(columnOrConditions);
|
|
242
|
+
}
|
|
243
|
+
return this;
|
|
244
|
+
}
|
|
245
|
+
// WHERE IN
|
|
246
|
+
whereIn(column, values) {
|
|
247
|
+
this.knexQuery.whereIn(column, values);
|
|
248
|
+
return this;
|
|
249
|
+
}
|
|
250
|
+
// WHERE NOT IN
|
|
251
|
+
whereNotIn(column, values) {
|
|
252
|
+
this.knexQuery.whereIn(column, values);
|
|
253
|
+
return this;
|
|
254
|
+
}
|
|
255
|
+
// WHERE MATCH
|
|
256
|
+
whereMatch(column, value) {
|
|
257
|
+
this.knexQuery.whereRaw(`MATCH (${String(column)}) AGAINST (?)`, [
|
|
258
|
+
value
|
|
259
|
+
]);
|
|
260
|
+
return this;
|
|
261
|
+
}
|
|
262
|
+
// WHERE 괄호 그룹핑
|
|
263
|
+
whereGroup(callback) {
|
|
264
|
+
this.knexQuery.where((builder)=>{
|
|
265
|
+
const group = new WhereGroup(builder);
|
|
266
|
+
callback(group);
|
|
267
|
+
});
|
|
268
|
+
return this;
|
|
269
|
+
}
|
|
270
|
+
orWhereGroup(callback) {
|
|
271
|
+
this.knexQuery.orWhere((builder)=>{
|
|
272
|
+
const group = new WhereGroup(builder);
|
|
273
|
+
callback(group);
|
|
274
|
+
});
|
|
275
|
+
return this;
|
|
276
|
+
}
|
|
277
|
+
orderBy(column, direction = "asc") {
|
|
278
|
+
this.knexQuery.orderBy(column, direction);
|
|
279
|
+
return this;
|
|
280
|
+
}
|
|
281
|
+
// 기본 쿼리 메서드들
|
|
282
|
+
limit(count) {
|
|
283
|
+
this.knexQuery.limit(count);
|
|
284
|
+
return this;
|
|
285
|
+
}
|
|
286
|
+
offset(count) {
|
|
287
|
+
this.knexQuery.offset(count);
|
|
288
|
+
return this;
|
|
289
|
+
}
|
|
290
|
+
groupBy(...columns) {
|
|
291
|
+
this.knexQuery.groupBy(...columns);
|
|
292
|
+
return this;
|
|
293
|
+
}
|
|
294
|
+
// HAVING 구현
|
|
295
|
+
having(...conditions) {
|
|
296
|
+
if (conditions.length === 1) {
|
|
297
|
+
// having("COUNT(*) > 10")
|
|
298
|
+
this.knexQuery.having(conditions[0]);
|
|
299
|
+
} else if (conditions.length === 3) {
|
|
300
|
+
// having("count", ">", 10)
|
|
301
|
+
this.knexQuery.having(conditions[0], conditions[1], conditions[2]);
|
|
302
|
+
} else {
|
|
303
|
+
throw new Error("Invalid having arguments");
|
|
304
|
+
}
|
|
305
|
+
return this;
|
|
306
|
+
}
|
|
307
|
+
// 실행 메서드들 - thenable 구현
|
|
308
|
+
then(onfulfilled, onrejected) {
|
|
309
|
+
Naite.t("puri-query", this.toQuery());
|
|
310
|
+
return this.knexQuery.then(onfulfilled, onrejected);
|
|
311
|
+
}
|
|
312
|
+
catch(onrejected) {
|
|
313
|
+
return this.knexQuery.catch(onrejected);
|
|
314
|
+
}
|
|
315
|
+
finally(onfinally) {
|
|
316
|
+
return this.knexQuery.finally(onfinally);
|
|
317
|
+
}
|
|
318
|
+
// 하나만 쿼리
|
|
319
|
+
first() {
|
|
320
|
+
this.knexQuery.first();
|
|
321
|
+
return new ResolvedPuri(this.knexQuery);
|
|
322
|
+
}
|
|
323
|
+
// 쿼리한 레코드에서 특정 컬럼만 추출한 배열 리턴
|
|
324
|
+
pluck(column) {
|
|
325
|
+
this.knexQuery.pluck(column);
|
|
326
|
+
return new ResolvedPuri(this.knexQuery);
|
|
327
|
+
}
|
|
328
|
+
// INSERT
|
|
329
|
+
insert(data) {
|
|
330
|
+
this.knexQuery.insert(data);
|
|
331
|
+
return new ResolvedPuri(this.knexQuery);
|
|
332
|
+
}
|
|
333
|
+
// UPDATE
|
|
334
|
+
update(data) {
|
|
335
|
+
this.knexQuery.update(data);
|
|
336
|
+
return new ResolvedPuri(this.knexQuery);
|
|
337
|
+
}
|
|
338
|
+
// Increment
|
|
339
|
+
increment(column, value) {
|
|
340
|
+
if (value <= 0) {
|
|
341
|
+
throw new Error("Increment value must be greater than 0");
|
|
342
|
+
}
|
|
343
|
+
this.knexQuery.increment(column, value);
|
|
344
|
+
return new ResolvedPuri(this.knexQuery);
|
|
345
|
+
}
|
|
346
|
+
// Decrement
|
|
347
|
+
decrement(column, value) {
|
|
348
|
+
if (value <= 0) {
|
|
349
|
+
throw new Error("Decrement value must be greater than 0");
|
|
350
|
+
}
|
|
351
|
+
this.knexQuery.decrement(column, value);
|
|
352
|
+
return new ResolvedPuri(this.knexQuery);
|
|
353
|
+
}
|
|
354
|
+
// DELETE
|
|
355
|
+
delete() {
|
|
356
|
+
this.knexQuery.delete();
|
|
357
|
+
return new ResolvedPuri(this.knexQuery);
|
|
358
|
+
}
|
|
359
|
+
// 확인 쿼리 리턴
|
|
360
|
+
toQuery() {
|
|
361
|
+
return this.knexQuery.toQuery();
|
|
362
|
+
}
|
|
363
|
+
// 쿼리 디버깅 로그 출력
|
|
364
|
+
debug() {
|
|
365
|
+
console.log(`${chalk.cyan("[Puri Debug]")} ${chalk.yellow(this.toQuery())}`);
|
|
366
|
+
return this;
|
|
367
|
+
}
|
|
368
|
+
formatSQL(unformatted) {
|
|
369
|
+
// SQL 예약어 목록
|
|
370
|
+
const keywords = [
|
|
371
|
+
"SELECT",
|
|
372
|
+
"FROM",
|
|
373
|
+
"WHERE",
|
|
374
|
+
"INSERT",
|
|
375
|
+
"INTO",
|
|
376
|
+
"VALUES",
|
|
377
|
+
"UPDATE",
|
|
378
|
+
"DELETE",
|
|
379
|
+
"CREATE",
|
|
380
|
+
"TABLE",
|
|
381
|
+
"ALTER",
|
|
382
|
+
"DROP",
|
|
383
|
+
"JOIN",
|
|
384
|
+
"ON",
|
|
385
|
+
"INNER",
|
|
386
|
+
"LEFT",
|
|
387
|
+
"RIGHT",
|
|
388
|
+
"FULL",
|
|
389
|
+
"OUTER",
|
|
390
|
+
"GROUP",
|
|
391
|
+
"BY",
|
|
392
|
+
"ORDER",
|
|
393
|
+
"HAVING",
|
|
394
|
+
"DISTINCT",
|
|
395
|
+
"LIMIT",
|
|
396
|
+
"OFFSET",
|
|
397
|
+
"AS",
|
|
398
|
+
"AND",
|
|
399
|
+
"OR",
|
|
400
|
+
"NOT",
|
|
401
|
+
"IN",
|
|
402
|
+
"LIKE",
|
|
403
|
+
"IS",
|
|
404
|
+
"NULL",
|
|
405
|
+
"CASE",
|
|
406
|
+
"WHEN",
|
|
407
|
+
"THEN",
|
|
408
|
+
"ELSE",
|
|
409
|
+
"END",
|
|
410
|
+
"UNION",
|
|
411
|
+
"ALL",
|
|
412
|
+
"EXISTS",
|
|
413
|
+
"BETWEEN"
|
|
414
|
+
];
|
|
415
|
+
let formatted = unformatted;
|
|
416
|
+
// 예약어를 대문자로 변환
|
|
417
|
+
keywords.forEach((keyword)=>{
|
|
418
|
+
const regex = new RegExp(`\\b${keyword}\\b`, "gi");
|
|
419
|
+
formatted = formatted.replace(regex, keyword.toUpperCase());
|
|
420
|
+
});
|
|
421
|
+
// 주요 절 앞에 줄바꿈 추가
|
|
422
|
+
const majorClauses = [
|
|
423
|
+
"SELECT",
|
|
424
|
+
"FROM",
|
|
425
|
+
"WHERE",
|
|
426
|
+
"GROUP BY",
|
|
427
|
+
"ORDER BY",
|
|
428
|
+
"HAVING",
|
|
429
|
+
"LIMIT",
|
|
430
|
+
"UNION"
|
|
431
|
+
];
|
|
432
|
+
majorClauses.forEach((clause)=>{
|
|
433
|
+
const regex = new RegExp(`\\s+(${clause})\\s+`, "gi");
|
|
434
|
+
formatted = formatted.replace(regex, `\n${clause.toUpperCase()} `);
|
|
435
|
+
});
|
|
436
|
+
// JOIN 절 처리
|
|
437
|
+
formatted = formatted.replace(/\s+((?:INNER|LEFT|RIGHT|FULL OUTER)\s+)?JOIN\s+/gi, "\n$1JOIN ");
|
|
438
|
+
// AND, OR 조건 처리
|
|
439
|
+
formatted = formatted.replace(/\s+(AND|OR)\s+/gi, "\n $1 ");
|
|
440
|
+
// 괄호 처리 및 들여쓰기
|
|
441
|
+
const lines = formatted.split("\n");
|
|
442
|
+
const indentedLines = [];
|
|
443
|
+
let indentLevel = 0;
|
|
444
|
+
for (let line of lines){
|
|
445
|
+
const trimmedLine = line.trim();
|
|
446
|
+
if (!trimmedLine) continue;
|
|
447
|
+
// 닫는 괄호가 있으면 들여쓰기 레벨 감소
|
|
448
|
+
const closingParens = (trimmedLine.match(/\)/g) || []).length;
|
|
449
|
+
const openingParens = (trimmedLine.match(/\(/g) || []).length;
|
|
450
|
+
if (closingParens > 0 && openingParens === 0) {
|
|
451
|
+
indentLevel = Math.max(0, indentLevel - closingParens);
|
|
452
|
+
}
|
|
453
|
+
// 현재 들여쓰기 적용
|
|
454
|
+
const indent = " ".repeat(indentLevel);
|
|
455
|
+
indentedLines.push(indent + trimmedLine);
|
|
456
|
+
// 여는 괄호가 있으면 들여쓰기 레벨 증가
|
|
457
|
+
if (openingParens > closingParens) {
|
|
458
|
+
indentLevel += openingParens - closingParens;
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
return indentedLines.join("\n").trim();
|
|
462
|
+
}
|
|
463
|
+
// Knex 쿼리 빌더 직접 접근
|
|
464
|
+
raw() {
|
|
465
|
+
return this.knexQuery;
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
export class WhereGroup {
|
|
469
|
+
builder;
|
|
470
|
+
constructor(builder){
|
|
471
|
+
this.builder = builder;
|
|
472
|
+
}
|
|
473
|
+
where(...args) {
|
|
474
|
+
this.builder.where(args[0], ...args.slice(1));
|
|
475
|
+
return this;
|
|
476
|
+
}
|
|
477
|
+
orWhere(...args) {
|
|
478
|
+
this.builder.orWhere(args[0], ...args.slice(1));
|
|
479
|
+
return this;
|
|
480
|
+
}
|
|
481
|
+
whereGroup(callback) {
|
|
482
|
+
this.builder.where((subBuilder)=>{
|
|
483
|
+
const subGroup = new WhereGroup(subBuilder);
|
|
484
|
+
callback(subGroup);
|
|
485
|
+
});
|
|
486
|
+
return this;
|
|
487
|
+
}
|
|
488
|
+
orWhereGroup(callback) {
|
|
489
|
+
this.builder.orWhere((subBuilder)=>{
|
|
490
|
+
const subGroup = new WhereGroup(subBuilder);
|
|
491
|
+
callback(subGroup);
|
|
492
|
+
});
|
|
493
|
+
return this;
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
export class JoinClauseGroup {
|
|
497
|
+
callback;
|
|
498
|
+
constructor(callback){
|
|
499
|
+
this.callback = callback;
|
|
500
|
+
}
|
|
501
|
+
// ON(AND) 구현
|
|
502
|
+
on(...args) {
|
|
503
|
+
this.callback.on(...args);
|
|
504
|
+
return this;
|
|
505
|
+
}
|
|
506
|
+
// ON(OR) 구현
|
|
507
|
+
orOn(...args) {
|
|
508
|
+
this.callback.orOn(...args);
|
|
509
|
+
return this;
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
/*
|
|
513
|
+
TResolved: 쿼리 실행 후 반환될 결과 타입
|
|
514
|
+
_TReturning: 추후 RETURNING 절에 사용될 타입
|
|
515
|
+
*/ export class ResolvedPuri {
|
|
516
|
+
knexQuery;
|
|
517
|
+
constructor(knexQuery){
|
|
518
|
+
this.knexQuery = knexQuery;
|
|
519
|
+
}
|
|
520
|
+
toQuery() {
|
|
521
|
+
return this.knexQuery.toQuery();
|
|
522
|
+
}
|
|
523
|
+
debug() {
|
|
524
|
+
console.log(`${chalk.cyan("[Puri Debug]")} ${chalk.yellow(this.toQuery())}`);
|
|
525
|
+
return this;
|
|
526
|
+
}
|
|
527
|
+
then(onfulfilled, onrejected) {
|
|
528
|
+
Naite.t("puri-query", this.toQuery());
|
|
529
|
+
return this.knexQuery.then(onfulfilled, onrejected);
|
|
530
|
+
}
|
|
531
|
+
catch(onrejected) {
|
|
532
|
+
return this.knexQuery.catch(onrejected);
|
|
533
|
+
}
|
|
534
|
+
finally(onfinally) {
|
|
535
|
+
return this.knexQuery.finally(onfinally);
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9kYXRhYmFzZS9wdXJpLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0eXBlIHsgS25leCB9IGZyb20gXCJrbmV4XCI7XG5pbXBvcnQgdHlwZSB7XG4gIEF2YWlsYWJsZUNvbHVtbnMsXG4gIFNlbGVjdE9iamVjdCxcbiAgUGFyc2VTZWxlY3RPYmplY3QsXG4gIFdoZXJlQ29uZGl0aW9uLFxuICBDb21wYXJpc29uT3BlcmF0b3IsXG4gIEV4dHJhY3RDb2x1bW5UeXBlLFxuICBTcWxFeHByZXNzaW9uLFxuICBFeHBhbmQsXG4gIEZ1bGx0ZXh0Q29sdW1ucyxcbiAgUmVzdWx0QXZhaWxhYmxlQ29sdW1ucyxcbiAgSW5zZXJ0RGF0YSxcbiAgU2luZ2xlVGFibGVWYWx1ZSxcbn0gZnJvbSBcIi4vcHVyaS50eXBlc1wiO1xuaW1wb3J0IGNoYWxrIGZyb20gXCJjaGFsa1wiO1xuaW1wb3J0IGFzc2VydCBmcm9tIFwiYXNzZXJ0XCI7XG5pbXBvcnQgeyBOYWl0ZSB9IGZyb20gXCIuLi9uYWl0ZS9uYWl0ZVwiO1xuXG5leHBvcnQgY2xhc3MgUHVyaTxUU2NoZW1hLCBUVGFibGVzIGV4dGVuZHMgUmVjb3JkPHN0cmluZywgYW55PiwgVFJlc3VsdD4ge1xuICBwcml2YXRlIGtuZXhRdWVyeTogS25leC5RdWVyeUJ1aWxkZXI7XG5cbiAgLy8g7IOd7ISx7J6QIOyLnOq3uOuLiOyymOuTpFxuICBjb25zdHJ1Y3RvcihrbmV4OiBLbmV4LCB0YWJsZU5hbWU6IHN0cmluZyk7XG4gIGNvbnN0cnVjdG9yKFxuICAgIGtuZXg6IEtuZXgsXG4gICAgdGFibGVTcGVjOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmcgfCBQdXJpPFRTY2hlbWEsIGFueSwgYW55Pj5cbiAgKTtcbiAgY29uc3RydWN0b3IoXG4gICAgcHVibGljIGtuZXg6IEtuZXgsXG4gICAgdGFibGVOYW1lT3JTcGVjOiBhbnlcbiAgKSB7XG4gICAgaWYgKHR5cGVvZiB0YWJsZU5hbWVPclNwZWMgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgIC8vIENhc2U6IG5ldyBQdXJpKGtuZXgsIFwidXNlcnNcIilcbiAgICAgIHRoaXMua25leFF1ZXJ5ID0gdGhpcy5rbmV4KHRhYmxlTmFtZU9yU3BlYykuZnJvbSh0YWJsZU5hbWVPclNwZWMpO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIHRhYmxlTmFtZU9yU3BlYyA9PT0gXCJvYmplY3RcIikge1xuICAgICAgY29uc3QgZW50cmllcyA9IE9iamVjdC5lbnRyaWVzKHRhYmxlTmFtZU9yU3BlYyk7XG4gICAgICBpZiAoZW50cmllcy5sZW5ndGggIT09IDEpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGFibGUgc3BlYyBtdXN0IGhhdmUgZXhhY3RseSBvbmUgZW50cnlcIik7XG4gICAgICB9XG4gICAgICBhc3NlcnQoZW50cmllc1swXSk7XG4gICAgICBjb25zdCBbYWxpYXMsIHNwZWNdID0gZW50cmllc1swXTtcbiAgICAgIGlmICh0eXBlb2Ygc3BlYyA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgICB0aGlzLmtuZXhRdWVyeSA9IHRoaXMua25leChzcGVjKS5mcm9tKHsgW2FsaWFzXTogc3BlYyB9KTtcbiAgICAgIH0gZWxzZSBpZiAoc3BlYyBpbnN0YW5jZW9mIFB1cmkpIHtcbiAgICAgICAgY29uc3Qgc3VicXVlcnlCdWlsZGVyID0gc3BlYy5yYXcoKTtcbiAgICAgICAgdGhpcy5rbmV4UXVlcnkgPSB0aGlzLmtuZXguZnJvbShzdWJxdWVyeUJ1aWxkZXIuYXMoYWxpYXMpKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIkludmFsaWQgdGFibGUgc3BlY2lmaWNhdGlvblwiKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiSW52YWxpZCB0YWJsZSBzcGVjaWZpY2F0aW9uXCIpO1xuICAgIH1cbiAgfVxuXG4gIC8vIFN0YXRpYyBTUUwgaGVscGVyIGZ1bmN0aW9ucyBmb3IgU0VMRUNUXG4gIHN0YXRpYyBjb3VudChjb2x1bW46IHN0cmluZyA9IFwiKlwiKTogU3FsRXhwcmVzc2lvbjxcIm51bWJlclwiPiB7XG4gICAgcmV0dXJuIHtcbiAgICAgIF90eXBlOiBcInNxbF9leHByZXNzaW9uXCIsXG4gICAgICBfcmV0dXJuOiBcIm51bWJlclwiLFxuICAgICAgX3NxbDogYENPVU5UKCR7Y29sdW1ufSlgLFxuICAgIH07XG4gIH1cbiAgc3RhdGljIHN1bShjb2x1bW46IHN0cmluZyk6IFNxbEV4cHJlc3Npb248XCJudW1iZXJcIj4ge1xuICAgIHJldHVybiB7XG4gICAgICBfdHlwZTogXCJzcWxfZXhwcmVzc2lvblwiLFxuICAgICAgX3JldHVybjogXCJudW1iZXJcIixcbiAgICAgIF9zcWw6IGBTVU0oJHtjb2x1bW59KWAsXG4gICAgfTtcbiAgfVxuICBzdGF0aWMgYXZnKGNvbHVtbjogc3RyaW5nKTogU3FsRXhwcmVzc2lvbjxcIm51bWJlclwiPiB7XG4gICAgcmV0dXJuIHtcbiAgICAgIF90eXBlOiBcInNxbF9leHByZXNzaW9uXCIsXG4gICAgICBfcmV0dXJuOiBcIm51bWJlclwiLFxuICAgICAgX3NxbDogYEFWRygke2NvbHVtbn0pYCxcbiAgICB9O1xuICB9XG4gIHN0YXRpYyBtYXgoY29sdW1uOiBzdHJpbmcpOiBTcWxFeHByZXNzaW9uPFwibnVtYmVyXCI+IHtcbiAgICByZXR1cm4ge1xuICAgICAgX3R5cGU6IFwic3FsX2V4cHJlc3Npb25cIixcbiAgICAgIF9yZXR1cm46IFwibnVtYmVyXCIsXG4gICAgICBfc3FsOiBgTUFYKCR7Y29sdW1ufSlgLFxuICAgIH07XG4gIH1cbiAgc3RhdGljIG1pbihjb2x1bW46IHN0cmluZyk6IFNxbEV4cHJlc3Npb248XCJudW1iZXJcIj4ge1xuICAgIHJldHVybiB7XG4gICAgICBfdHlwZTogXCJzcWxfZXhwcmVzc2lvblwiLFxuICAgICAgX3JldHVybjogXCJudW1iZXJcIixcbiAgICAgIF9zcWw6IGBNSU4oJHtjb2x1bW59KWAsXG4gICAgfTtcbiAgfVxuICBzdGF0aWMgY29uY2F0KC4uLmFyZ3M6IHN0cmluZ1tdKTogU3FsRXhwcmVzc2lvbjxcInN0cmluZ1wiPiB7XG4gICAgcmV0dXJuIHtcbiAgICAgIF90eXBlOiBcInNxbF9leHByZXNzaW9uXCIsXG4gICAgICBfcmV0dXJuOiBcInN0cmluZ1wiLFxuICAgICAgX3NxbDogYENPTkNBVCgke2FyZ3Muam9pbihcIiwgXCIpfSlgLFxuICAgIH07XG4gIH1cbiAgc3RhdGljIHVwcGVyKGNvbHVtbjogc3RyaW5nKTogU3FsRXhwcmVzc2lvbjxcInN0cmluZ1wiPiB7XG4gICAgcmV0dXJuIHtcbiAgICAgIF90eXBlOiBcInNxbF9leHByZXNzaW9uXCIsXG4gICAgICBfcmV0dXJuOiBcInN0cmluZ1wiLFxuICAgICAgX3NxbDogYFVQUEVSKCR7Y29sdW1ufSlgLFxuICAgIH07XG4gIH1cbiAgc3RhdGljIGxvd2VyKGNvbHVtbjogc3RyaW5nKTogU3FsRXhwcmVzc2lvbjxcInN0cmluZ1wiPiB7XG4gICAgcmV0dXJuIHtcbiAgICAgIF90eXBlOiBcInNxbF9leHByZXNzaW9uXCIsXG4gICAgICBfcmV0dXJuOiBcInN0cmluZ1wiLFxuICAgICAgX3NxbDogYExPV0VSKCR7Y29sdW1ufSlgLFxuICAgIH07XG4gIH1cblxuICAvLyBSYXcgZnVuY3Rpb25zIGZvciBTRUxFQ1RcbiAgc3RhdGljIHJhd1N0cmluZyhzcWw6IHN0cmluZyk6IFNxbEV4cHJlc3Npb248XCJzdHJpbmdcIj4ge1xuICAgIHJldHVybiB7IF90eXBlOiBcInNxbF9leHByZXNzaW9uXCIsIF9yZXR1cm46IFwic3RyaW5nXCIsIF9zcWw6IHNxbCB9O1xuICB9XG4gIHN0YXRpYyByYXdOdW1iZXIoc3FsOiBzdHJpbmcpOiBTcWxFeHByZXNzaW9uPFwibnVtYmVyXCI+IHtcbiAgICByZXR1cm4geyBfdHlwZTogXCJzcWxfZXhwcmVzc2lvblwiLCBfcmV0dXJuOiBcIm51bWJlclwiLCBfc3FsOiBzcWwgfTtcbiAgfVxuICBzdGF0aWMgcmF3Qm9vbGVhbihzcWw6IHN0cmluZyk6IFNxbEV4cHJlc3Npb248XCJib29sZWFuXCI+IHtcbiAgICByZXR1cm4geyBfdHlwZTogXCJzcWxfZXhwcmVzc2lvblwiLCBfcmV0dXJuOiBcImJvb2xlYW5cIiwgX3NxbDogc3FsIH07XG4gIH1cbiAgc3RhdGljIHJhd0RhdGUoc3FsOiBzdHJpbmcpOiBTcWxFeHByZXNzaW9uPFwiZGF0ZVwiPiB7XG4gICAgcmV0dXJuIHsgX3R5cGU6IFwic3FsX2V4cHJlc3Npb25cIiwgX3JldHVybjogXCJkYXRlXCIsIF9zcWw6IHNxbCB9O1xuICB9XG5cbiAgLy8gU0VMRUNUIChvdmVyd3JpdGUpXG4gIHNlbGVjdDxUU2VsZWN0IGV4dGVuZHMgU2VsZWN0T2JqZWN0PFRUYWJsZXM+PihcbiAgICBzZWxlY3RPYmo6IFRTZWxlY3RcbiAgKTogUHVyaTxUU2NoZW1hLCBUVGFibGVzLCBQYXJzZVNlbGVjdE9iamVjdDxUVGFibGVzLCBUU2VsZWN0Pj4ge1xuICAgIGNvbnN0IHNlbGVjdENsYXVzZXM6IChzdHJpbmcgfCBLbmV4LlJhdylbXSA9IFtdO1xuXG4gICAgZm9yIChjb25zdCBbYWxpYXMsIGNvbHVtbk9yRnVuY3Rpb25dIG9mIE9iamVjdC5lbnRyaWVzKHNlbGVjdE9iaikpIHtcbiAgICAgIGlmIChcbiAgICAgICAgdHlwZW9mIGNvbHVtbk9yRnVuY3Rpb24gPT09IFwib2JqZWN0XCIgJiZcbiAgICAgICAgY29sdW1uT3JGdW5jdGlvbi5fdHlwZSA9PT0gXCJzcWxfZXhwcmVzc2lvblwiXG4gICAgICApIHtcbiAgICAgICAgLy8gU1FMIO2VqOyImOyduCDqsr3smrBcbiAgICAgICAgc2VsZWN0Q2xhdXNlcy5wdXNoKFxuICAgICAgICAgIHRoaXMua25leC5yYXcoYCR7Y29sdW1uT3JGdW5jdGlvbi5fc3FsfSBhcyAke2FsaWFzfWApXG4gICAgICAgICk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyDsnbzrsJgg7Lus65+87J24IOqyveyasFxuICAgICAgICBjb25zdCBjb2x1bW5QYXRoID0gY29sdW1uT3JGdW5jdGlvbiBhcyBzdHJpbmc7XG4gICAgICAgIGlmIChhbGlhcyA9PT0gY29sdW1uUGF0aCkge1xuICAgICAgICAgIC8vIGFsaWFz7JmAIOy7rOufvOuqheydtCDqsJnsnLzrqbQgYWxpYXMg7IOd6561XG4gICAgICAgICAgc2VsZWN0Q2xhdXNlcy5wdXNoKGNvbHVtblBhdGgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIGFsaWFzIOyngOyglVxuICAgICAgICAgIHNlbGVjdENsYXVzZXMucHVzaChgJHtjb2x1bW5QYXRofSBhcyAke2FsaWFzfWApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5rbmV4UXVlcnkuc2VsZWN0KHNlbGVjdENsYXVzZXMpO1xuICAgIHJldHVybiB0aGlzIGFzIGFueTtcbiAgfVxuXG4gIC8vIFNFTEVDVCAoc2VsZWN064qUIG92ZXJ3cml0ZSwgYXBwZW5kU2VsZWN064qUIGFwcGVuZClcbiAgYXBwZW5kU2VsZWN0PFRTZWxlY3QgZXh0ZW5kcyBTZWxlY3RPYmplY3Q8VFRhYmxlcz4+KFxuICAgIHNlbGVjdE9iajogVFNlbGVjdFxuICApOiBQdXJpPFRTY2hlbWEsIFRUYWJsZXMsIFRSZXN1bHQgJiBQYXJzZVNlbGVjdE9iamVjdDxUVGFibGVzLCBUU2VsZWN0Pj4ge1xuICAgIHJldHVybiB0aGlzLnNlbGVjdChzZWxlY3RPYmopIGFzIGFueTtcbiAgfVxuXG4gIC8vIFNFTEVDVCAqXG4gIHNlbGVjdEFsbCgpOiB0aGlzIHtcbiAgICB0aGlzLmtuZXhRdWVyeS5zZWxlY3QoXCIqXCIpO1xuICAgIHJldHVybiB0aGlzIGFzIGFueTtcbiAgfVxuXG4gIC8vIEpPSU46IOyEnOu4jOy/vOumrCArIEFsaWFzXG4gIGpvaW48VEpvaW5BbGlhcyBleHRlbmRzIHN0cmluZywgVFN1YlJlc3VsdD4oXG4gICAgdGFibGVTcGVjOiB7IFtLIGluIFRKb2luQWxpYXNdOiBQdXJpPFRTY2hlbWEsIGFueSwgVFN1YlJlc3VsdD4gfSxcbiAgICBsZWZ0OiBBdmFpbGFibGVDb2x1bW5zPFRUYWJsZXM+LFxuICAgIHJpZ2h0OiBgJHtUSm9pbkFsaWFzfS4ke2tleW9mIFRTdWJSZXN1bHQgJiBzdHJpbmd9YFxuICApOiBQdXJpPFxuICAgIFRTY2hlbWEsXG4gICAgVFRhYmxlcyAmIFJlY29yZDxUSm9pbkFsaWFzLCBUU3ViUmVzdWx0PiwgLy8g7ISc67iM7L+866as7J2YIFRSZXN1bHRcbiAgICBUUmVzdWx0XG4gID47XG4gIC8vIEpPSU46IO2FjOydtOu4lCArIEFsaWFzXG4gIGpvaW48VEpvaW5UYWJsZSBleHRlbmRzIGtleW9mIFRTY2hlbWEsIFRKb2luQWxpYXMgZXh0ZW5kcyBzdHJpbmc+KFxuICAgIHRhYmxlU3BlYzogeyBbSyBpbiBUSm9pbkFsaWFzXTogVEpvaW5UYWJsZSB9LFxuICAgIGxlZnQ6IEF2YWlsYWJsZUNvbHVtbnM8VFRhYmxlcz4sXG4gICAgcmlnaHQ6IGAke1RKb2luQWxpYXN9LiR7a2V5b2YgVFNjaGVtYVtUSm9pblRhYmxlXSAmIHN0cmluZ31gXG4gICk6IFB1cmk8XG4gICAgVFNjaGVtYSxcbiAgICBUVGFibGVzICYgUmVjb3JkPFRKb2luQWxpYXMsIFRTY2hlbWFbVEpvaW5UYWJsZV0+LCAvLyBUVGFibGVzIO2ZleyepSFcbiAgICBUUmVzdWx0XG4gID47XG4gIC8vIEpPSU46IO2FjOydtOu4lOuqhVxuICBqb2luPFRKb2luVGFibGUgZXh0ZW5kcyBrZXlvZiBUU2NoZW1hPihcbiAgICB0YWJsZU5hbWU6IFRKb2luVGFibGUsXG4gICAgbGVmdDogQXZhaWxhYmxlQ29sdW1uczxUVGFibGVzPixcbiAgICByaWdodDogYCR7VEpvaW5UYWJsZSAmIHN0cmluZ30uJHtrZXlvZiBUU2NoZW1hW1RKb2luVGFibGVdICYgc3RyaW5nfWBcbiAgKTogUHVyaTxcbiAgICBUU2NoZW1hLFxuICAgIFRUYWJsZXMgJiBSZWNvcmQ8VEpvaW5UYWJsZSwgVFNjaGVtYVtUSm9pblRhYmxlXT4sIC8vIO2FjOydtOu4lOuqheydtCDtgqRcbiAgICBUUmVzdWx0XG4gID47XG4gIC8vIEpPSU46IOyEnOu4jOy/vOumrCArIEFsaWFzICsg7L2c67CxXG4gIGpvaW48VEpvaW5BbGlhcyBleHRlbmRzIHN0cmluZywgVFN1YlJlc3VsdD4oXG4gICAgdGFibGVTcGVjOiB7IFtLIGluIFRKb2luQWxpYXNdOiBQdXJpPFRTY2hlbWEsIGFueSwgVFN1YlJlc3VsdD4gfSxcbiAgICBjYWxsYmFjazogKFxuICAgICAgajogSm9pbkNsYXVzZUdyb3VwPFRUYWJsZXMsIFJlY29yZDxUSm9pbkFsaWFzLCBUU3ViUmVzdWx0Pj5cbiAgICApID0+IHZvaWRcbiAgKTogUHVyaTxUU2NoZW1hLCBUVGFibGVzICYgUmVjb3JkPFRKb2luQWxpYXMsIFRTdWJSZXN1bHQ+LCBUUmVzdWx0PjtcbiAgLy8gSk9JTjog7YWM7J2067iUICsgQWxpYXMgKyDsvZzrsLFcbiAgam9pbjxUSm9pblRhYmxlIGV4dGVuZHMga2V5b2YgVFNjaGVtYSwgVEpvaW5BbGlhcyBleHRlbmRzIHN0cmluZz4oXG4gICAgdGFibGVTcGVjOiB7IFtLIGluIFRKb2luQWxpYXNdOiBUSm9pblRhYmxlIH0sXG4gICAgY2FsbGJhY2s6IChcbiAgICAgIGo6IEpvaW5DbGF1c2VHcm91cDxUVGFibGVzLCBSZWNvcmQ8VEpvaW5BbGlhcywgVFNjaGVtYVtUSm9pblRhYmxlXT4+XG4gICAgKSA9PiB2b2lkXG4gICk6IFB1cmk8VFNjaGVtYSwgVFRhYmxlcyAmIFJlY29yZDxUSm9pbkFsaWFzLCBUU2NoZW1hW1RKb2luVGFibGVdPiwgVFJlc3VsdD47XG4gIC8vIEpPSU46IO2FjOydtOu4lOuqhSArIOy9nOuwsVxuICBqb2luPFRKb2luVGFibGUgZXh0ZW5kcyBrZXlvZiBUU2NoZW1hPihcbiAgICB0YWJsZU5hbWU6IFRKb2luVGFibGUsXG4gICAgY2FsbGJhY2s6IChcbiAgICAgIGo6IEpvaW5DbGF1c2VHcm91cDxUVGFibGVzLCBSZWNvcmQ8VEpvaW5UYWJsZSwgVFNjaGVtYVtUSm9pblRhYmxlXT4+XG4gICAgKSA9PiB2b2lkXG4gICk6IFB1cmk8VFNjaGVtYSwgVFRhYmxlcyAmIFJlY29yZDxUSm9pblRhYmxlLCBUU2NoZW1hW1RKb2luVGFibGVdPiwgVFJlc3VsdD47XG4gIC8vIEpPSU4g7Iuk7KCcIOq1rO2YhFxuICBqb2luKHRhYmxlTmFtZU9yU3BlYzogYW55LCAuLi5hcmdzOiBhbnlbXSk6IGFueSB7XG4gICAgcmV0dXJuIHRoaXMuX19jb21tb25Kb2luKFwiam9pblwiLCB0YWJsZU5hbWVPclNwZWMsIC4uLmFyZ3MpO1xuICB9XG5cbiAgLy8gTEVGVCBKT0lOOiDshJzruIzsv7zrpqwgKyBBbGlhc1xuICBsZWZ0Sm9pbjxUSm9pbkFsaWFzIGV4dGVuZHMgc3RyaW5nLCBUU3ViUmVzdWx0PihcbiAgICB0YWJsZVNwZWM6IHsgW0sgaW4gVEpvaW5BbGlhc106IFB1cmk8VFNjaGVtYSwgYW55LCBUU3ViUmVzdWx0PiB9LFxuICAgIGxlZnQ6IEF2YWlsYWJsZUNvbHVtbnM8VFRhYmxlcz4sXG4gICAgcmlnaHQ6IGAke1RKb2luQWxpYXN9LiR7a2V5b2YgVFN1YlJlc3VsdCAmIHN0cmluZ31gXG4gICk6IFB1cmk8XG4gICAgVFNjaGVtYSxcbiAgICBUVGFibGVzICYgUmVjb3JkPFRKb2luQWxpYXMsIFRTdWJSZXN1bHQ+LCAvLyDshJzruIzsv7zrpqzsnZggVFJlc3VsdFxuICAgIFRSZXN1bHRcbiAgPjtcbiAgLy8gTEVGVCBKT0lOOiDthYzsnbTruJQgKyBBbGlhc1xuICBsZWZ0Sm9pbjxUSm9pblRhYmxlIGV4dGVuZHMga2V5b2YgVFNjaGVtYSwgVEpvaW5BbGlhcyBleHRlbmRzIHN0cmluZz4oXG4gICAgdGFibGVTcGVjOiB7IFtLIGluIFRKb2luQWxpYXNdOiBUSm9pblRhYmxlIH0sXG4gICAgbGVmdDogQXZhaWxhYmxlQ29sdW1uczxUVGFibGVzPixcbiAgICByaWdodDogYCR7VEpvaW5BbGlhc30uJHtrZXlvZiBUU2NoZW1hW1RKb2luVGFibGVdICYgc3RyaW5nfWBcbiAgKTogUHVyaTxcbiAgICBUU2NoZW1hLFxuICAgIFRUYWJsZXMgJiBSZWNvcmQ8VEpvaW5BbGlhcywgVFNjaGVtYVtUSm9pblRhYmxlXT4sIC8vIFRUYWJsZXMg7ZmV7J6lIVxuICAgIFRSZXN1bHRcbiAgPjtcbiAgLy8gTEVGVCBKT0lOOiDthYzsnbTruJTrqoVcbiAgbGVmdEpvaW48VEpvaW5UYWJsZSBleHRlbmRzIGtleW9mIFRTY2hlbWE+KFxuICAgIHRhYmxlTmFtZTogVEpvaW5UYWJsZSxcbiAgICBsZWZ0OiBBdmFpbGFibGVDb2x1bW5zPFRUYWJsZXM+LFxuICAgIHJpZ2h0OiBgJHtUSm9pblRhYmxlICYgc3RyaW5nfS4ke2tleW9mIFRTY2hlbWFbVEpvaW5UYWJsZV0gJiBzdHJpbmd9YFxuICApOiBQdXJpPFxuICAgIFRTY2hlbWEsXG4gICAgVFRhYmxlcyAmIFJlY29yZDxUSm9pblRhYmxlLCBUU2NoZW1hW1RKb2luVGFibGVdPiwgLy8g7YWM7J2067iU66qF7J20IO2CpFxuICAgIFRSZXN1bHRcbiAgPjtcbiAgLy8gTEVGVCBKT0lOOiDshJzruIzsv7zrpqwgKyBBbGlhcyArIOy9nOuwsVxuICBsZWZ0Sm9pbjxUSm9pbkFsaWFzIGV4dGVuZHMgc3RyaW5nLCBUU3ViUmVzdWx0PihcbiAgICB0YWJsZVNwZWM6IHsgW0sgaW4gVEpvaW5BbGlhc106IFB1cmk8VFNjaGVtYSwgYW55LCBUU3ViUmVzdWx0PiB9LFxuICAgIGNhbGxiYWNrOiAoXG4gICAgICBqOiBKb2luQ2xhdXNlR3JvdXA8VFRhYmxlcywgUmVjb3JkPFRKb2luQWxpYXMsIFRTdWJSZXN1bHQ+PlxuICAgICkgPT4gdm9pZFxuICApOiBQdXJpPFRTY2hlbWEsIFRUYWJsZXMgJiBSZWNvcmQ8VEpvaW5BbGlhcywgVFN1YlJlc3VsdD4sIFRSZXN1bHQ+O1xuICAvLyBMRUZUIEpPSU46IO2FjOydtOu4lCArIEFsaWFzICsg7L2c67CxXG4gIGxlZnRKb2luPFRKb2luVGFibGUgZXh0ZW5kcyBrZXlvZiBUU2NoZW1hLCBUSm9pbkFsaWFzIGV4dGVuZHMgc3RyaW5nPihcbiAgICB0YWJsZVNwZWM6IHsgW0sgaW4gVEpvaW5BbGlhc106IFRKb2luVGFibGUgfSxcbiAgICBjYWxsYmFjazogKFxuICAgICAgajogSm9pbkNsYXVzZUdyb3VwPFRUYWJsZXMsIFJlY29yZDxUSm9pbkFsaWFzLCBUU2NoZW1hW1RKb2luVGFibGVdPj5cbiAgICApID0+IHZvaWRcbiAgKTogUHVyaTxUU2NoZW1hLCBUVGFibGVzICYgUmVjb3JkPFRKb2luQWxpYXMsIFRTY2hlbWFbVEpvaW5UYWJsZV0+LCBUUmVzdWx0PjtcbiAgLy8gTEVGVCBKT0lOOiDthYzsnbTruJTrqoUgKyDsvZzrsLFcbiAgbGVmdEpvaW48VEpvaW5UYWJsZSBleHRlbmRzIGtleW9mIFRTY2hlbWE+KFxuICAgIHRhYmxlTmFtZTogVEpvaW5UYWJsZSxcbiAgICBjYWxsYmFjazogKFxuICAgICAgajogSm9pbkNsYXVzZUdyb3VwPFRUYWJsZXMsIFJlY29yZDxUSm9pblRhYmxlLCBUU2NoZW1hW1RKb2luVGFibGVdPj5cbiAgICApID0+IHZvaWRcbiAgKTogUHVyaTxUU2NoZW1hLCBUVGFibGVzICYgUmVjb3JkPFRKb2luVGFibGUsIFRTY2hlbWFbVEpvaW5UYWJsZV0+LCBUUmVzdWx0PjtcbiAgLy8gTEVGVCBKT0lOIOyLpOygnCDqtaztmIRcbiAgbGVmdEpvaW4odGFibGVOYW1lT3JTcGVjOiBhbnksIC4uLmFyZ3M6IGFueVtdKTogYW55IHtcbiAgICByZXR1cm4gdGhpcy5fX2NvbW1vbkpvaW4oXCJsZWZ0Sm9pblwiLCB0YWJsZU5hbWVPclNwZWMsIC4uLmFyZ3MpO1xuICB9XG5cbiAgX19jb21tb25Kb2luKFxuICAgIGpvaW5UeXBlOiBcImpvaW5cIiB8IFwibGVmdEpvaW5cIixcbiAgICB0YWJsZU5hbWVPclNwZWM6IGFueSxcbiAgICAuLi5hcmdzOiBhbnlbXVxuICApOiB0aGlzIHtcbiAgICBpZiAodHlwZW9mIHRhYmxlTmFtZU9yU3BlYyA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgLy8gQ2FzZSAxOiBqb2luKFwicG9zdHNcIiwgLi4uKVxuICAgICAgY29uc3QgdGFibGVOYW1lID0gdGFibGVOYW1lT3JTcGVjO1xuXG4gICAgICBpZiAoYXJncy5sZW5ndGggPT09IDEgJiYgdHlwZW9mIGFyZ3NbMF0gPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAvLyBqb2luKFwicG9zdHNcIiwgY2FsbGJhY2spXG4gICAgICAgIGNvbnN0IGNhbGxiYWNrID0gYXJnc1swXTtcbiAgICAgICAgdGhpcy5rbmV4UXVlcnlbam9pblR5cGVdKHRhYmxlTmFtZSwgKGpvaW5DbGF1c2UpID0+IHtcbiAgICAgICAgICBjYWxsYmFjayhuZXcgSm9pbkNsYXVzZUdyb3VwKGpvaW5DbGF1c2UpKTtcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBqb2luKFwicG9zdHNcIiwgbGVmdCwgcmlnaHQpXG4gICAgICAgIGNvbnN0IFtsZWZ0LCByaWdodF0gPSBhcmdzO1xuICAgICAgICB0aGlzLmtuZXhRdWVyeVtqb2luVHlwZV0odGFibGVOYW1lLCBsZWZ0LCByaWdodCk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgdGFibGVOYW1lT3JTcGVjID09PSBcIm9iamVjdFwiKSB7XG4gICAgICAvLyBDYXNlIDI6IGpvaW4oeyBhbGlhczogXCJ0YWJsZVwiIH0sIC4uLikgb3Igam9pbih7IGFsaWFzOiBzdWJxdWVyeSB9LCAuLi4pXG4gICAgICBjb25zdCBlbnRyaWVzID0gT2JqZWN0LmVudHJpZXModGFibGVOYW1lT3JTcGVjKTtcbiAgICAgIGlmIChlbnRyaWVzLmxlbmd0aCAhPT0gMSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUYWJsZSBzcGVjIG11c3QgaGF2ZSBleGFjdGx5IG9uZSBlbnRyeVwiKTtcbiAgICAgIH1cbiAgICAgIGFzc2VydChlbnRyaWVzWzBdKTtcbiAgICAgIGNvbnN0IFtbYWxpYXMsIHNwZWNdXSA9IGVudHJpZXM7XG5cbiAgICAgIGlmICh0eXBlb2Ygc3BlYyA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgICAvLyDthYzsnbTruJQ6IGpvaW4oeyBwOiBcInBvc3RzXCIgfSwgLi4uKVxuICAgICAgICBpZiAoYXJncy5sZW5ndGggPT09IDEgJiYgdHlwZW9mIGFyZ3NbMF0gPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgIC8vIENhbGxiYWNrXG4gICAgICAgICAgY29uc3QgY2FsbGJhY2sgPSBhcmdzWzBdO1xuICAgICAgICAgIHRoaXMua25leFF1ZXJ5W2pvaW5UeXBlXSh7IFthbGlhc106IHNwZWMgfSwgKGpvaW5DbGF1c2UpID0+IHtcbiAgICAgICAgICAgIGNhbGxiYWNrKG5ldyBKb2luQ2xhdXNlR3JvdXAoam9pbkNsYXVzZSkpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIFNpbXBsZVxuICAgICAgICAgIGNvbnN0IFtsZWZ0LCByaWdodF0gPSBhcmdzO1xuICAgICAgICAgIHRoaXMua25leFF1ZXJ5W2pvaW5UeXBlXSh7IFthbGlhc106IHNwZWMgfSwgbGVmdCwgcmlnaHQpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKHNwZWMgaW5zdGFuY2VvZiBQdXJpKSB7XG4gICAgICAgIC8vIOyEnOu4jOy/vOumrDogam9pbih7IHNxOiBzdWJxdWVyeSB9LCAuLi4pXG4gICAgICAgIGlmIChhcmdzLmxlbmd0aCA9PT0gMSAmJiB0eXBlb2YgYXJnc1swXSA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgLy8gQ2FsbGJhY2tcbiAgICAgICAgICBjb25zdCBjYWxsYmFjayA9IGFyZ3NbMF07XG4gICAgICAgICAgdGhpcy5rbmV4UXVlcnlbam9pblR5cGVdKHNwZWMucmF3KCkuYXMoYWxpYXMpLCAoam9pbkNsYXVzZSkgPT4ge1xuICAgICAgICAgICAgY2FsbGJhY2sobmV3IEpvaW5DbGF1c2VHcm91cChqb2luQ2xhdXNlKSk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gU2ltcGxlXG4gICAgICAgICAgY29uc3QgW2xlZnQsIHJpZ2h0XSA9IGFyZ3M7XG4gICAgICAgICAgdGhpcy5rbmV4UXVlcnlbam9pblR5cGVdKHNwZWMucmF3KCkuYXMoYWxpYXMpLCBsZWZ0LCByaWdodCk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIkludmFsaWQgdGFibGUgc3BlY2lmaWNhdGlvblwiKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiSW52YWxpZCBhcmd1bWVudHNcIik7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvLyBXSEVSRTog6rCd7LK0IC0g7IKs7JqpOiAud2hlcmUoeyBcInUuaWRcIjogMSwgXCJ1LnN0YXR1c1wiOiBcImFjdGl2ZVwiIH0pXG4gIHdoZXJlKGNvbmRpdGlvbnM6IFdoZXJlQ29uZGl0aW9uPFRUYWJsZXM+KTogdGhpcztcbiAgLy8gV0hFUkU6IOy7rOufvCAtIOyCrOyaqTogLndoZXJlKFwidS5pZFwiLCAxKVxuICB3aGVyZTxUQ29sdW1uIGV4dGVuZHMgQXZhaWxhYmxlQ29sdW1uczxUVGFibGVzPj4oXG4gICAgY29sdW1uOiBUQ29sdW1uLFxuICAgIHZhbHVlOiBFeHRyYWN0Q29sdW1uVHlwZTxUVGFibGVzLCBUQ29sdW1uICYgc3RyaW5nPlxuICApOiB0aGlzO1xuICAvLyBXSEVSRTog7Lus65+8IC0g7IKs7JqpOiAud2hlcmUoXCJ1LmlkXCIsIFwiPlwiLCAxMClcbiAgd2hlcmU8VENvbHVtbiBleHRlbmRzIEF2YWlsYWJsZUNvbHVtbnM8VFRhYmxlcz4+KFxuICAgIGNvbHVtbjogVENvbHVtbixcbiAgICBvcGVyYXRvcjogQ29tcGFyaXNvbk9wZXJhdG9yIHwgXCJsaWtlXCIgfCBcIm5vdCBsaWtlXCIsXG4gICAgdmFsdWU6IEV4dHJhY3RDb2x1bW5UeXBlPFRUYWJsZXMsIFRDb2x1bW4gJiBzdHJpbmc+XG4gICk6IHRoaXM7XG4gIC8vIFdIRVJFOiDsu6zrn7wgLSDsgqzsmqk6IC53aGVyZShcInUuaWRcIiwgXCJsaWtlXCIsIFwiJXRlc3QlXCIpXG4gIHdoZXJlKGNvbHVtbk9yQ29uZGl0aW9uczogYW55LCBvcGVyYXRvck9yVmFsdWU/OiBhbnksIHZhbHVlPzogYW55KTogdGhpcyB7XG4gICAgaWYgKHR5cGVvZiBjb2x1bW5PckNvbmRpdGlvbnMgPT09IFwib2JqZWN0XCIpIHtcbiAgICAgIHRoaXMua25leFF1ZXJ5LndoZXJlKGNvbHVtbk9yQ29uZGl0aW9ucyk7XG4gICAgfSBlbHNlIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAyKSB7XG4gICAgICBpZiAob3BlcmF0b3JPclZhbHVlID09PSBudWxsKSB7XG4gICAgICAgIHRoaXMua25leFF1ZXJ5LndoZXJlTnVsbChjb2x1bW5PckNvbmRpdGlvbnMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cbiAgICAgIHRoaXMua25leFF1ZXJ5LndoZXJlKGNvbHVtbk9yQ29uZGl0aW9ucywgb3BlcmF0b3JPclZhbHVlKTtcbiAgICB9IGVsc2UgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDMpIHtcbiAgICAgIGlmICh2YWx1ZSA9PT0gbnVsbCkge1xuICAgICAgICBpZiAob3BlcmF0b3JPclZhbHVlID09PSBcIiE9XCIpIHtcbiAgICAgICAgICB0aGlzLmtuZXhRdWVyeS53aGVyZU5vdE51bGwoY29sdW1uT3JDb25kaXRpb25zKTtcbiAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfSBlbHNlIGlmIChvcGVyYXRvck9yVmFsdWUgPT09IFwiPVwiKSB7XG4gICAgICAgICAgdGhpcy5rbmV4UXVlcnkud2hlcmVOdWxsKGNvbHVtbk9yQ29uZGl0aW9ucyk7XG4gICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHRoaXMua25leFF1ZXJ5LndoZXJlKGNvbHVtbk9yQ29uZGl0aW9ucywgb3BlcmF0b3JPclZhbHVlLCB2YWx1ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMua25leFF1ZXJ5LndoZXJlKGNvbHVtbk9yQ29uZGl0aW9ucyk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLy8gV0hFUkUgSU5cbiAgd2hlcmVJbjxUQ29sdW1uIGV4dGVuZHMgQXZhaWxhYmxlQ29sdW1uczxUVGFibGVzPj4oXG4gICAgY29sdW1uOiBUQ29sdW1uLFxuICAgIHZhbHVlczogRXh0cmFjdENvbHVtblR5cGU8VFRhYmxlcywgVENvbHVtbiAmIHN0cmluZz5bXVxuICApOiBQdXJpPFRTY2hlbWEsIFRUYWJsZXMsIFRSZXN1bHQ+IHtcbiAgICB0aGlzLmtuZXhRdWVyeS53aGVyZUluKGNvbHVtbiwgdmFsdWVzKTtcbiAgICByZXR1cm4gdGhpcyBhcyBhbnk7XG4gIH1cblxuICAvLyBXSEVSRSBOT1QgSU5cbiAgd2hlcmVOb3RJbjxUQ29sdW1uIGV4dGVuZHMgQXZhaWxhYmxlQ29sdW1uczxUVGFibGVzPj4oXG4gICAgY29sdW1uOiBUQ29sdW1uLFxuICAgIHZhbHVlczogRXh0cmFjdENvbHVtblR5cGU8VFRhYmxlcywgVENvbHVtbiAmIHN0cmluZz5bXVxuICApOiBQdXJpPFRTY2hlbWEsIFRUYWJsZXMsIFRSZXN1bHQ+IHtcbiAgICB0aGlzLmtuZXhRdWVyeS53aGVyZUluKGNvbHVtbiwgdmFsdWVzKTtcbiAgICByZXR1cm4gdGhpcyBhcyBhbnk7XG4gIH1cblxuICAvLyBXSEVSRSBNQVRDSFxuICB3aGVyZU1hdGNoPFRDb2x1bW4gZXh0ZW5kcyBGdWxsdGV4dENvbHVtbnM8VFRhYmxlcz4+KFxuICAgIGNvbHVtbjogVENvbHVtbixcbiAgICB2YWx1ZTogc3RyaW5nXG4gICk6IHRoaXMge1xuICAgIHRoaXMua25leFF1ZXJ5LndoZXJlUmF3KGBNQVRDSCAoJHtTdHJpbmcoY29sdW1uKX0pIEFHQUlOU1QgKD8pYCwgW3ZhbHVlXSk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvLyBXSEVSRSDqtITtmLgg6re466O57ZWRXG4gIHdoZXJlR3JvdXAoY2FsbGJhY2s6IChnOiBXaGVyZUdyb3VwPFRUYWJsZXM+KSA9PiB2b2lkKTogdGhpcyB7XG4gICAgdGhpcy5rbmV4UXVlcnkud2hlcmUoKGJ1aWxkZXIpID0+IHtcbiAgICAgIGNvbnN0IGdyb3VwID0gbmV3IFdoZXJlR3JvdXA8VFRhYmxlcz4oYnVpbGRlcik7XG4gICAgICBjYWxsYmFjayhncm91cCk7XG4gICAgfSk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cbiAgb3JXaGVyZUdyb3VwKGNhbGxiYWNrOiAoZzogV2hlcmVHcm91cDxUVGFibGVzPikgPT4gdm9pZCk6IHRoaXMge1xuICAgIHRoaXMua25leFF1ZXJ5Lm9yV2hlcmUoKGJ1aWxkZXIpID0+IHtcbiAgICAgIGNvbnN0IGdyb3VwID0gbmV3IFdoZXJlR3JvdXA8VFRhYmxlcz4oYnVpbGRlcik7XG4gICAgICBjYWxsYmFjayhncm91cCk7XG4gICAgfSk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvLyBPUkRFUiBCWVxuICBvcmRlckJ5PFRDb2x1bW4gZXh0ZW5kcyBSZXN1bHRBdmFpbGFibGVDb2x1bW5zPFRUYWJsZXMsIFRSZXN1bHQ+PihcbiAgICBjb2x1bW46IFRDb2x1bW4sXG4gICAgZGlyZWN0aW9uOiBcImFzY1wiIHwgXCJkZXNjXCJcbiAgKTogdGhpcztcbiAgb3JkZXJCeShjb2x1bW46IHN0cmluZywgZGlyZWN0aW9uOiBcImFzY1wiIHwgXCJkZXNjXCIgPSBcImFzY1wiKTogdGhpcyB7XG4gICAgdGhpcy5rbmV4UXVlcnkub3JkZXJCeShjb2x1bW4sIGRpcmVjdGlvbik7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvLyDquLDrs7gg7L+866asIOuplOyEnOuTnOuTpFxuICBsaW1pdChjb3VudDogbnVtYmVyKTogdGhpcyB7XG4gICAgdGhpcy5rbmV4UXVlcnkubGltaXQoY291bnQpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgb2Zmc2V0KGNvdW50OiBudW1iZXIpOiB0aGlzIHtcbiAgICB0aGlzLmtuZXhRdWVyeS5vZmZzZXQoY291bnQpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLy8gR1JPVVAgQllcbiAgZ3JvdXBCeTxUQ29sdW1ucyBleHRlbmRzIFJlc3VsdEF2YWlsYWJsZUNvbHVtbnM8VFRhYmxlcywgVFJlc3VsdD4+KFxuICAgIC4uLmNvbHVtbnM6IFRDb2x1bW5zW11cbiAgKTogdGhpcztcbiAgZ3JvdXBCeSguLi5jb2x1bW5zOiBzdHJpbmdbXSk6IHRoaXMge1xuICAgIHRoaXMua25leFF1ZXJ5Lmdyb3VwQnkoLi4uKGNvbHVtbnMgYXMgc3RyaW5nW10pKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8vIEhBVklOR1xuICBoYXZpbmcoY29uZGl0aW9uOiBzdHJpbmcpOiB0aGlzO1xuICBoYXZpbmc8VENvbHVtbiBleHRlbmRzIFJlc3VsdEF2YWlsYWJsZUNvbHVtbnM8VFRhYmxlcywgVFJlc3VsdD4+KFxuICAgIGNvbHVtbjogVENvbHVtbixcbiAgICBvcGVyYXRvcjogQ29tcGFyaXNvbk9wZXJhdG9yLFxuICAgIHZhbHVlOiBhbnlcbiAgKTogdGhpcztcbiAgLy8gSEFWSU5HIOq1rO2YhFxuICBoYXZpbmcoLi4uY29uZGl0aW9uczogYW55W10pOiB0aGlzIHtcbiAgICBpZiAoY29uZGl0aW9ucy5sZW5ndGggPT09IDEpIHtcbiAgICAgIC8vIGhhdmluZyhcIkNPVU5UKCopID4gMTBcIilcbiAgICAgIHRoaXMua25leFF1ZXJ5LmhhdmluZyhjb25kaXRpb25zWzBdKTtcbiAgICB9IGVsc2UgaWYgKGNvbmRpdGlvbnMubGVuZ3RoID09PSAzKSB7XG4gICAgICAvLyBoYXZpbmcoXCJjb3VudFwiLCBcIj5cIiwgMTApXG4gICAgICB0aGlzLmtuZXhRdWVyeS5oYXZpbmcoY29uZGl0aW9uc1swXSwgY29uZGl0aW9uc1sxXSwgY29uZGl0aW9uc1syXSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkludmFsaWQgaGF2aW5nIGFyZ3VtZW50c1wiKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvLyDsi6Ttlokg66mU7ISc65Oc65OkIC0gdGhlbmFibGUg6rWs7ZiEXG4gIHRoZW48VFJlc3VsdDEgPSBFeHBhbmQ8VFJlc3VsdD5bXSwgVFJlc3VsdDIgPSBuZXZlcj4oXG4gICAgb25mdWxmaWxsZWQ/OlxuICAgICAgfCAoKHZhbHVlOiBFeHBhbmQ8VFJlc3VsdD5bXSkgPT4gVFJlc3VsdDEgfCBQcm9taXNlTGlrZTxUUmVzdWx0MT4pXG4gICAgICB8IG51bGwsXG4gICAgb25yZWplY3RlZD86ICgocmVhc29uOiBhbnkpID0+IFRSZXN1bHQyIHwgUHJvbWlzZUxpa2U8VFJlc3VsdDI+KSB8IG51bGxcbiAgKTogUHJvbWlzZTxUUmVzdWx0MSB8IFRSZXN1bHQyPiB7XG4gICAgTmFpdGUudChcInB1cmktcXVlcnlcIiwgdGhpcy50b1F1ZXJ5KCkpO1xuICAgIHJldHVybiB0aGlzLmtuZXhRdWVyeS50aGVuKG9uZnVsZmlsbGVkIGFzIGFueSwgb25yZWplY3RlZCk7XG4gIH1cbiAgY2F0Y2g8VFJlc3VsdDIgPSBuZXZlcj4oXG4gICAgb25yZWplY3RlZD86ICgocmVhc29uOiBhbnkpID0+IFRSZXN1bHQyIHwgUHJvbWlzZUxpa2U8VFJlc3VsdDI+KSB8IG51bGxcbiAgKTogUHJvbWlzZTxUUmVzdWx0IHwgVFJlc3VsdDI+IHtcbiAgICByZXR1cm4gdGhpcy5rbmV4UXVlcnkuY2F0Y2gob25yZWplY3RlZCk7XG4gIH1cbiAgZmluYWxseShvbmZpbmFsbHk/OiAoKCkgPT4gdm9pZCkgfCBudWxsKTogUHJvbWlzZTxUUmVzdWx0PiB7XG4gICAgcmV0dXJuIHRoaXMua25leFF1ZXJ5LmZpbmFsbHkob25maW5hbGx5KTtcbiAgfVxuXG4gIC8vIO2VmOuCmOunjCDsv7zrpqxcbiAgZmlyc3QoKTogUmVzb2x2ZWRQdXJpPEV4cGFuZDxUUmVzdWx0PiwgbmV2ZXI+IHtcbiAgICB0aGlzLmtuZXhRdWVyeS5maXJzdCgpO1xuICAgIHJldHVybiBuZXcgUmVzb2x2ZWRQdXJpKHRoaXMua25leFF1ZXJ5KTtcbiAgfVxuXG4gIC8vIOy/vOumrO2VnCDroIjsvZTrk5zsl5DshJwg7Yq57KCVIOy7rOufvOunjCDstpTstpztlZwg67Cw7Je0IOumrO2EtFxuICBwbHVjazxcbiAgICBUQ29sdW1uIGV4dGVuZHMga2V5b2YgVFJlc3VsdCB8IFJlc3VsdEF2YWlsYWJsZUNvbHVtbnM8VFRhYmxlcywgVFJlc3VsdD4sXG4gID4oXG4gICAgY29sdW1uOiBUQ29sdW1uXG4gICk6IFJlc29sdmVkUHVyaTxcbiAgICBUQ29sdW1uIGV4dGVuZHMga2V5b2YgVFJlc3VsdFxuICAgICAgPyBUUmVzdWx0W1RDb2x1bW5dW11cbiAgICAgIDogRXh0cmFjdENvbHVtblR5cGU8VFRhYmxlcywgVENvbHVtbiAmIHN0cmluZz5bXSxcbiAgICBuZXZlclxuICA+IHtcbiAgICB0aGlzLmtuZXhRdWVyeS5wbHVjayhjb2x1bW4gYXMgc3RyaW5nKTtcbiAgICByZXR1cm4gbmV3IFJlc29sdmVkUHVyaSh0aGlzLmtuZXhRdWVyeSk7XG4gIH1cblxuICAvLyBJTlNFUlRcbiAgaW5zZXJ0KFxuICAgIGRhdGE6IEluc2VydERhdGE8U2luZ2xlVGFibGVWYWx1ZTxUVGFibGVzPj5cbiAgKTogUmVzb2x2ZWRQdXJpPFtudW1iZXJdLCBuZXZlcj4ge1xuICAgIHRoaXMua25leFF1ZXJ5Lmluc2VydChkYXRhKTtcbiAgICByZXR1cm4gbmV3IFJlc29sdmVkUHVyaSh0aGlzLmtuZXhRdWVyeSk7XG4gIH1cblxuICAvLyBVUERBVEVcbiAgdXBkYXRlKGRhdGE6IFdoZXJlQ29uZGl0aW9uPFRUYWJsZXM+KTogUmVzb2x2ZWRQdXJpPFRSZXN1bHQsIG51bWJlcj4ge1xuICAgIHRoaXMua25leFF1ZXJ5LnVwZGF0ZShkYXRhKTtcbiAgICByZXR1cm4gbmV3IFJlc29sdmVkUHVyaSh0aGlzLmtuZXhRdWVyeSk7XG4gIH1cblxuICAvLyBJbmNyZW1lbnRcbiAgaW5jcmVtZW50PFRDb2x1bW4gZXh0ZW5kcyBBdmFpbGFibGVDb2x1bW5zPFRUYWJsZXM+PihcbiAgICBjb2x1bW46IFRDb2x1bW4sXG4gICAgdmFsdWU6IG51bWJlclxuICApOiBSZXNvbHZlZFB1cmk8bnVtYmVyLCBuZXZlcj4ge1xuICAgIGlmICh2YWx1ZSA8PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJJbmNyZW1lbnQgdmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gMFwiKTtcbiAgICB9XG4gICAgdGhpcy5rbmV4UXVlcnkuaW5jcmVtZW50KGNvbHVtbiwgdmFsdWUpO1xuICAgIHJldHVybiBuZXcgUmVzb2x2ZWRQdXJpKHRoaXMua25leFF1ZXJ5KTtcbiAgfVxuICAvLyBEZWNyZW1lbnRcbiAgZGVjcmVtZW50PFRDb2x1bW4gZXh0ZW5kcyBBdmFpbGFibGVDb2x1bW5zPFRUYWJsZXM+PihcbiAgICBjb2x1bW46IFRDb2x1bW4sXG4gICAgdmFsdWU6IG51bWJlclxuICApOiBSZXNvbHZlZFB1cmk8bnVtYmVyLCBuZXZlcj4ge1xuICAgIGlmICh2YWx1ZSA8PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJEZWNyZW1lbnQgdmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gMFwiKTtcbiAgICB9XG4gICAgdGhpcy5rbmV4UXVlcnkuZGVjcmVtZW50KGNvbHVtbiwgdmFsdWUpO1xuICAgIHJldHVybiBuZXcgUmVzb2x2ZWRQdXJpKHRoaXMua25leFF1ZXJ5KTtcbiAgfVxuXG4gIC8vIERFTEVURVxuICBkZWxldGUoKTogUmVzb2x2ZWRQdXJpPG51bWJlciwgbmV2ZXI+IHtcbiAgICB0aGlzLmtuZXhRdWVyeS5kZWxldGUoKTtcbiAgICByZXR1cm4gbmV3IFJlc29sdmVkUHVyaSh0aGlzLmtuZXhRdWVyeSk7XG4gIH1cblxuICAvLyDtmZXsnbgg7L+866asIOumrO2EtFxuICB0b1F1ZXJ5KCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMua25leFF1ZXJ5LnRvUXVlcnkoKTtcbiAgfVxuXG4gIC8vIOy/vOumrCDrlJTrsoTquYUg66Gc6re4IOy2nOugpVxuICBkZWJ1ZygpOiB0aGlzIHtcbiAgICBjb25zb2xlLmxvZyhcbiAgICAgIGAke2NoYWxrLmN5YW4oXCJbUHVyaSBEZWJ1Z11cIil9ICR7Y2hhbGsueWVsbG93KHRoaXMudG9RdWVyeSgpKX1gXG4gICAgKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIGZvcm1hdFNRTCh1bmZvcm1hdHRlZDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICAvLyBTUUwg7JiI7JW97Ja0IOuqqeuhnVxuICAgIGNvbnN0IGtleXdvcmRzID0gW1xuICAgICAgXCJTRUxFQ1RcIixcbiAgICAgIFwiRlJPTVwiLFxuICAgICAgXCJXSEVSRVwiLFxuICAgICAgXCJJTlNFUlRcIixcbiAgICAgIFwiSU5UT1wiLFxuICAgICAgXCJWQUxVRVNcIixcbiAgICAgIFwiVVBEQVRFXCIsXG4gICAgICBcIkRFTEVURVwiLFxuICAgICAgXCJDUkVBVEVcIixcbiAgICAgIFwiVEFCTEVcIixcbiAgICAgIFwiQUxURVJcIixcbiAgICAgIFwiRFJPUFwiLFxuICAgICAgXCJKT0lOXCIsXG4gICAgICBcIk9OXCIsXG4gICAgICBcIklOTkVSXCIsXG4gICAgICBcIkxFRlRcIixcbiAgICAgIFwiUklHSFRcIixcbiAgICAgIFwiRlVMTFwiLFxuICAgICAgXCJPVVRFUlwiLFxuICAgICAgXCJHUk9VUFwiLFxuICAgICAgXCJCWVwiLFxuICAgICAgXCJPUkRFUlwiLFxuICAgICAgXCJIQVZJTkdcIixcbiAgICAgIFwiRElTVElOQ1RcIixcbiAgICAgIFwiTElNSVRcIixcbiAgICAgIFwiT0ZGU0VUXCIsXG4gICAgICBcIkFTXCIsXG4gICAgICBcIkFORFwiLFxuICAgICAgXCJPUlwiLFxuICAgICAgXCJOT1RcIixcbiAgICAgIFwiSU5cIixcbiAgICAgIFwiTElLRVwiLFxuICAgICAgXCJJU1wiLFxuICAgICAgXCJOVUxMXCIsXG4gICAgICBcIkNBU0VcIixcbiAgICAgIFwiV0hFTlwiLFxuICAgICAgXCJUSEVOXCIsXG4gICAgICBcIkVMU0VcIixcbiAgICAgIFwiRU5EXCIsXG4gICAgICBcIlVOSU9OXCIsXG4gICAgICBcIkFMTFwiLFxuICAgICAgXCJFWElTVFNcIixcbiAgICAgIFwiQkVUV0VFTlwiLFxuICAgIF07XG5cbiAgICBsZXQgZm9ybWF0dGVkID0gdW5mb3JtYXR0ZWQ7XG5cbiAgICAvLyDsmIjslb3slrTrpbwg64yA66y47J6Q66GcIOuzgO2ZmFxuICAgIGtleXdvcmRzLmZvckVhY2goKGtleXdvcmQpID0+IHtcbiAgICAgIGNvbnN0IHJlZ2V4ID0gbmV3IFJlZ0V4cChgXFxcXGIke2tleXdvcmR9XFxcXGJgLCBcImdpXCIpO1xuICAgICAgZm9ybWF0dGVkID0gZm9ybWF0dGVkLnJlcGxhY2UocmVnZXgsIGtleXdvcmQudG9VcHBlckNhc2UoKSk7XG4gICAgfSk7XG5cbiAgICAvLyDso7zsmpQg7KCIIOyVnuyXkCDspITrsJTqv4gg7LaU6rCAXG4gICAgY29uc3QgbWFqb3JDbGF1c2VzID0gW1xuICAgICAgXCJTRUxFQ1RcIixcbiAgICAgIFwiRlJPTVwiLFxuICAgICAgXCJXSEVSRVwiLFxuICAgICAgXCJHUk9VUCBCWVwiLFxuICAgICAgXCJPUkRFUiBCWVwiLFxuICAgICAgXCJIQVZJTkdcIixcbiAgICAgIFwiTElNSVRcIixcbiAgICAgIFwiVU5JT05cIixcbiAgICBdO1xuICAgIG1ham9yQ2xhdXNlcy5mb3JFYWNoKChjbGF1c2UpID0+IHtcbiAgICAgIGNvbnN0IHJlZ2V4ID0gbmV3IFJlZ0V4cChgXFxcXHMrKCR7Y2xhdXNlfSlcXFxccytgLCBcImdpXCIpO1xuICAgICAgZm9ybWF0dGVkID0gZm9ybWF0dGVkLnJlcGxhY2UocmVnZXgsIGBcXG4ke2NsYXVzZS50b1VwcGVyQ2FzZSgpfSBgKTtcbiAgICB9KTtcblxuICAgIC8vIEpPSU4g7KCIIOyymOumrFxuICAgIGZvcm1hdHRlZCA9IGZvcm1hdHRlZC5yZXBsYWNlKFxuICAgICAgL1xccysoKD86SU5ORVJ8TEVGVHxSSUdIVHxGVUxMIE9VVEVSKVxccyspP0pPSU5cXHMrL2dpLFxuICAgICAgXCJcXG4kMUpPSU4gXCJcbiAgICApO1xuXG4gICAgLy8gQU5ELCBPUiDsobDqsbQg7LKY66asXG4gICAgZm9ybWF0dGVkID0gZm9ybWF0dGVkLnJlcGxhY2UoL1xccysoQU5EfE9SKVxccysvZ2ksIFwiXFxuICAkMSBcIik7XG5cbiAgICAvLyDqtITtmLgg7LKY66asIOuwjyDrk6Tsl6zsk7DquLBcbiAgICBjb25zdCBsaW5lcyA9IGZvcm1hdHRlZC5zcGxpdChcIlxcblwiKTtcbiAgICBjb25zdCBpbmRlbnRlZExpbmVzID0gW107XG4gICAgbGV0IGluZGVudExldmVsID0gMDtcblxuICAgIGZvciAobGV0IGxpbmUgb2YgbGluZXMpIHtcbiAgICAgIGNvbnN0IHRyaW1tZWRMaW5lID0gbGluZS50cmltKCk7XG4gICAgICBpZiAoIXRyaW1tZWRMaW5lKSBjb250aW51ZTtcblxuICAgICAgLy8g64ur64qUIOq0hO2YuOqwgCDsnojsnLzrqbQg65Ok7Jes7JOw6riwIOugiOuyqCDqsJDshoxcbiAgICAgIGNvbnN0IGNsb3NpbmdQYXJlbnMgPSAodHJpbW1lZExpbmUubWF0Y2goL1xcKS9nKSB8fCBbXSkubGVuZ3RoO1xuICAgICAgY29uc3Qgb3BlbmluZ1BhcmVucyA9ICh0cmltbWVkTGluZS5tYXRjaCgvXFwoL2cpIHx8IFtdKS5sZW5ndGg7XG5cbiAgICAgIGlmIChjbG9zaW5nUGFyZW5zID4gMCAmJiBvcGVuaW5nUGFyZW5zID09PSAwKSB7XG4gICAgICAgIGluZGVudExldmVsID0gTWF0aC5tYXgoMCwgaW5kZW50TGV2ZWwgLSBjbG9zaW5nUGFyZW5zKTtcbiAgICAgIH1cblxuICAgICAgLy8g7ZiE7J6sIOuTpOyXrOyTsOq4sCDsoIHsmqlcbiAgICAgIGNvbnN0IGluZGVudCA9IFwiICBcIi5yZXBlYXQoaW5kZW50TGV2ZWwpO1xuICAgICAgaW5kZW50ZWRMaW5lcy5wdXNoKGluZGVudCArIHRyaW1tZWRMaW5lKTtcblxuICAgICAgLy8g7Jes64qUIOq0hO2YuOqwgCDsnojsnLzrqbQg65Ok7Jes7JOw6riwIOugiOuyqCDspp3qsIBcbiAgICAgIGlmIChvcGVuaW5nUGFyZW5zID4gY2xvc2luZ1BhcmVucykge1xuICAgICAgICBpbmRlbnRMZXZlbCArPSBvcGVuaW5nUGFyZW5zIC0gY2xvc2luZ1BhcmVucztcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gaW5kZW50ZWRMaW5lcy5qb2luKFwiXFxuXCIpLnRyaW0oKTtcbiAgfVxuXG4gIC8vIEtuZXgg7L+866asIOu5jOuNlCDsp4HsoJEg7KCR6re8XG4gIHJhdygpOiBLbmV4LlF1ZXJ5QnVpbGRlciB7XG4gICAgcmV0dXJuIHRoaXMua25leFF1ZXJ5O1xuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBXaGVyZUdyb3VwPFRUYWJsZXMgZXh0ZW5kcyBSZWNvcmQ8c3RyaW5nLCBhbnk+PiB7XG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgYnVpbGRlcjogS25leC5RdWVyeUJ1aWxkZXIpIHt9XG5cbiAgLy8gd2hlcmUg66mU7ISc65Oc65OkXG4gIHdoZXJlKGNvbmRpdGlvbnM6IFdoZXJlQ29uZGl0aW9uPFRUYWJsZXM+KTogdGhpcztcbiAgd2hlcmU8VENvbHVtbiBleHRlbmRzIEF2YWlsYWJsZUNvbHVtbnM8VFRhYmxlcz4+KFxuICAgIGNvbHVtbjogVENvbHVtbixcbiAgICB2YWx1ZTogRXh0cmFjdENvbHVtblR5cGU8VFRhYmxlcywgVENvbHVtbiAmIHN0cmluZz5cbiAgKTogdGhpcztcbiAgd2hlcmU8VENvbHVtbiBleHRlbmRzIEF2YWlsYWJsZUNvbHVtbnM8VFRhYmxlcz4+KFxuICAgIGNvbHVtbjogVENvbHVtbixcbiAgICBvcGVyYXRvcjogQ29tcGFyaXNvbk9wZXJhdG9yLFxuICAgIHZhbHVlOiBFeHRyYWN0Q29sdW1uVHlwZTxUVGFibGVzLCBUQ29sdW1uICYgc3RyaW5nPlxuICApOiB0aGlzO1xuICB3aGVyZSguLi5hcmdzOiBhbnlbXSk6IFdoZXJlR3JvdXA8VFRhYmxlcz4ge1xuICAgIHRoaXMuYnVpbGRlci53aGVyZShhcmdzWzBdLCAuLi5hcmdzLnNsaWNlKDEpKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8vIG9yV2hlcmUg66mU7ISc65Oc65OkXG4gIG9yV2hlcmUoY29uZGl0aW9uczogV2hlcmVDb25kaXRpb248VFRhYmxlcz4pOiB0aGlzO1xuICBvcldoZXJlPFRDb2x1bW4gZXh0ZW5kcyBBdmFpbGFibGVDb2x1bW5zPFRUYWJsZXM+PihcbiAgICBjb2x1bW46IFRDb2x1bW4sXG4gICAgdmFsdWU6IEV4dHJhY3RDb2x1bW5UeXBlPFRUYWJsZXMsIFRDb2x1bW4gJiBzdHJpbmc+XG4gICk6IHRoaXM7XG4gIG9yV2hlcmU8VENvbHVtbiBleHRlbmRzIEF2YWlsYWJsZUNvbHVtbnM8VFRhYmxlcz4+KFxuICAgIGNvbHVtbjogVENvbHVtbixcbiAgICBvcGVyYXRvcjogQ29tcGFyaXNvbk9wZXJhdG9yLFxuICAgIHZhbHVlOiBFeHRyYWN0Q29sdW1uVHlwZTxUVGFibGVzLCBUQ29sdW1uICYgc3RyaW5nPlxuICApOiB0aGlzO1xuICBvcldoZXJlKC4uLmFyZ3M6IGFueVtdKTogV2hlcmVHcm91cDxUVGFibGVzPiB7XG4gICAgdGhpcy5idWlsZGVyLm9yV2hlcmUoYXJnc1swXSwgLi4uYXJncy5zbGljZSgxKSk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvLyDspJHssqkg6re466O5XG4gIHdoZXJlR3JvdXAoY2FsbGJhY2s6IChnOiBXaGVyZUdyb3VwPFRUYWJsZXM+KSA9PiB2b2lkKTogdGhpcztcbiAgd2hlcmVHcm91cChjYWxsYmFjazogKGc6IFdoZXJlR3JvdXA8VFRhYmxlcz4pID0+IHZvaWQpOiBXaGVyZUdyb3VwPFRUYWJsZXM+IHtcbiAgICB0aGlzLmJ1aWxkZXIud2hlcmUoKHN1YkJ1aWxkZXIpID0+IHtcbiAgICAgIGNvbnN0IHN1Ykdyb3VwID0gbmV3IFdoZXJlR3JvdXA8VFRhYmxlcz4oc3ViQnVpbGRlcik7XG4gICAgICBjYWxsYmFjayhzdWJHcm91cCk7XG4gICAgfSk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cbiAgb3JXaGVyZUdyb3VwKGNhbGxiYWNrOiAoZzogV2hlcmVHcm91cDxUVGFibGVzPikgPT4gdm9pZCk6IHRoaXM7XG4gIG9yV2hlcmVHcm91cChcbiAgICBjYWxsYmFjazogKGc6IFdoZXJlR3JvdXA8VFRhYmxlcz4pID0+IHZvaWRcbiAgKTogV2hlcmVHcm91cDxUVGFibGVzPiB7XG4gICAgdGhpcy5idWlsZGVyLm9yV2hlcmUoKHN1YkJ1aWxkZXIpID0+IHtcbiAgICAgIGNvbnN0IHN1Ykdyb3VwID0gbmV3IFdoZXJlR3JvdXA8VFRhYmxlcz4oc3ViQnVpbGRlcik7XG4gICAgICBjYWxsYmFjayhzdWJHcm91cCk7XG4gICAgfSk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIEpvaW5DbGF1c2VHcm91cDxcbiAgVExlZnQgZXh0ZW5kcyBSZWNvcmQ8c3RyaW5nLCBhbnk+LFxuICBUUmlnaHQgZXh0ZW5kcyBSZWNvcmQ8c3RyaW5nLCBhbnk+LFxuPiB7XG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgY2FsbGJhY2s6IEtuZXguSm9pbkNsYXVzZSkge31cblxuICAvLyBPTihBTkQpOiDsu6zrn7wgPSDsu6zrn7xcbiAgb24obGVmdDogQXZhaWxhYmxlQ29sdW1uczxUTGVmdD4sIHJpZ2h0OiBBdmFpbGFibGVDb2x1bW5zPFRSaWdodD4pOiB0aGlzO1xuICAvLyBPTihBTkQpOiDsu6zrn7wgKOyXsOyCsOyekCkg7Lus65+8XG4gIG9uKFxuICAgIGxlZnQ6IEF2YWlsYWJsZUNvbHVtbnM8VExlZnQ+LFxuICAgIG9wZXJhdG9yOiBDb21wYXJpc29uT3BlcmF0b3IsXG4gICAgcmlnaHQ6IEF2YWlsYWJsZUNvbHVtbnM8VFJpZ2h0PlxuICApOiB0aGlzO1xuICAvLyBPTihBTkQpOiDsvZzrsLFcbiAgb24oY2FsbGJhY2s6IChuZXN0ZWQ6IEpvaW5DbGF1c2VHcm91cDxUTGVmdCwgVFJpZ2h0PikgPT4gdm9pZCk6IHRoaXM7XG4gIC8vIE9OKEFORCkg6rWs7ZiEXG4gIG9uKC4uLmFyZ3M6IGFueVtdKTogdGhpcyB7XG4gICAgdGhpcy5jYWxsYmFjay5vbiguLi4oYXJncyBhcyBbc3RyaW5nLCBzdHJpbmddKSk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvLyBPTihPUik6IOy7rOufvCA9IOy7rOufvFxuICBvck9uKGxlZnQ6IEF2YWlsYWJsZUNvbHVtbnM8VExlZnQ+LCByaWdodDogQXZhaWxhYmxlQ29sdW1uczxUUmlnaHQ+KTogdGhpcztcbiAgLy8gT04oT1IpOiDsu6zrn7wgKOyXsOyCsOyekCkg7Lus65+8XG4gIG9yT24oXG4gICAgbGVmdDogQXZhaWxhYmxlQ29sdW1uczxUTGVmdD4sXG4gICAgb3BlcmF0b3I6IENvbXBhcmlzb25PcGVyYXRvcixcbiAgICByaWdodDogQXZhaWxhYmxlQ29sdW1uczxUUmlnaHQ+XG4gICk6IHRoaXM7XG4gIC8vIE9OKE9SKTog7L2c67CxXG4gIG9yT24oY2FsbGJhY2s6IChuZXN0ZWQ6IEpvaW5DbGF1c2VHcm91cDxUTGVmdCwgVFJpZ2h0PikgPT4gdm9pZCk6IHRoaXM7XG4gIC8vIE9OKE9SKSDqtaztmIRcbiAgb3JPbiguLi5hcmdzOiBhbnlbXSk6IHRoaXMge1xuICAgIHRoaXMuY2FsbGJhY2sub3JPbiguLi4oYXJncyBhcyBbc3RyaW5nLCBzdHJpbmddKSk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cbn1cblxuLypcbiAgVFJlc29sdmVkOiDsv7zrpqwg7Iuk7ZaJIO2bhCDrsJjtmZjrkKAg6rKw6rO8IO2DgOyehVxuICBfVFJldHVybmluZzog7LaU7ZuEIFJFVFVSTklORyDsoIjsl5Ag7IKs7Jqp65CgIO2DgOyehVxuKi9cbmV4cG9ydCBjbGFzcyBSZXNvbHZlZFB1cmk8VFJlc29sdmVkLCBfVFJldHVybmluZz4ge1xuICBjb25zdHJ1Y3RvcihwdWJsaWMga25leFF1ZXJ5OiBLbmV4LlF1ZXJ5QnVpbGRlcikge31cblxuICB0b1F1ZXJ5KCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMua25leFF1ZXJ5LnRvUXVlcnkoKTtcbiAgfVxuXG4gIGRlYnVnKCk6IHRoaXMge1xuICAgIGNvbnNvbGUubG9nKFxuICAgICAgYCR7Y2hhbGsuY3lhbihcIltQdXJpIERlYnVnXVwiKX0gJHtjaGFsay55ZWxsb3codGhpcy50b1F1ZXJ5KCkpfWBcbiAgICApO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgdGhlbjxUUmVzdWx0MSA9IFRSZXNvbHZlZCwgVFJlc3VsdDIgPSBuZXZlcj4oXG4gICAgb25mdWxmaWxsZWQ/OlxuICAgICAgfCAoKHZhbHVlOiBUUmVzb2x2ZWQpID0+IFRSZXN1bHQxIHwgUHJvbWlzZUxpa2U8VFJlc3VsdDE+KVxuICAgICAgfCBudWxsLFxuICAgIG9ucmVqZWN0ZWQ/OiAoKHJlYXNvbjogYW55KSA9PiBUUmVzdWx0MiB8IFByb21pc2VMaWtlPFRSZXN1bHQyPikgfCBudWxsXG4gICk6IFByb21pc2U8VFJlc3VsdDEgfCBUUmVzdWx0Mj4ge1xuICAgIE5haXRlLnQoXCJwdXJpLXF1ZXJ5XCIsIHRoaXMudG9RdWVyeSgpKTtcbiAgICByZXR1cm4gdGhpcy5rbmV4UXVlcnkudGhlbihvbmZ1bGZpbGxlZCBhcyBhbnksIG9ucmVqZWN0ZWQpO1xuICB9XG4gIGNhdGNoPFRSZXN1bHQyID0gbmV2ZXI+KFxuICAgIG9ucmVqZWN0ZWQ/OiAoKHJlYXNvbjogYW55KSA9PiBUUmVzdWx0MiB8IFByb21pc2VMaWtlPFRSZXN1bHQyPikgfCBudWxsXG4gICk6IFByb21pc2U8VFJlc29sdmVkIHwgVFJlc3VsdDI+IHtcbiAgICByZXR1cm4gdGhpcy5rbmV4UXVlcnkuY2F0Y2gob25yZWplY3RlZCk7XG4gIH1cbiAgZmluYWxseShvbmZpbmFsbHk/OiAoKCkgPT4gdm9pZCkgfCBudWxsKTogUHJvbWlzZTxUUmVzb2x2ZWQ+IHtcbiAgICByZXR1cm4gdGhpcy5rbmV4UXVlcnkuZmluYWxseShvbmZpbmFsbHkpO1xuICB9XG59XG4iXSwibmFtZXMiOlsiY2hhbGsiLCJhc3NlcnQiLCJOYWl0ZSIsIlB1cmkiLCJrbmV4UXVlcnkiLCJrbmV4IiwidGFibGVOYW1lT3JTcGVjIiwiZnJvbSIsImVudHJpZXMiLCJPYmplY3QiLCJsZW5ndGgiLCJFcnJvciIsImFsaWFzIiwic3BlYyIsInN1YnF1ZXJ5QnVpbGRlciIsInJhdyIsImFzIiwiY291bnQiLCJjb2x1bW4iLCJfdHlwZSIsIl9yZXR1cm4iLCJfc3FsIiwic3VtIiwiYXZnIiwibWF4IiwibWluIiwiY29uY2F0IiwiYXJncyIsImpvaW4iLCJ1cHBlciIsImxvd2VyIiwicmF3U3RyaW5nIiwic3FsIiwicmF3TnVtYmVyIiwicmF3Qm9vbGVhbiIsInJhd0RhdGUiLCJzZWxlY3QiLCJzZWxlY3RPYmoiLCJzZWxlY3RDbGF1c2VzIiwiY29sdW1uT3JGdW5jdGlvbiIsInB1c2giLCJjb2x1bW5QYXRoIiwiYXBwZW5kU2VsZWN0Iiwic2VsZWN0QWxsIiwiX19jb21tb25Kb2luIiwibGVmdEpvaW4iLCJqb2luVHlwZSIsInRhYmxlTmFtZSIsImNhbGxiYWNrIiwiam9pbkNsYXVzZSIsIkpvaW5DbGF1c2VHcm91cCIsImxlZnQiLCJyaWdodCIsIndoZXJlIiwiY29sdW1uT3JDb25kaXRpb25zIiwib3BlcmF0b3JPclZhbHVlIiwidmFsdWUiLCJhcmd1bWVudHMiLCJ3aGVyZU51bGwiLCJ3aGVyZU5vdE51bGwiLCJ3aGVyZUluIiwidmFsdWVzIiwid2hlcmVOb3RJbiIsIndoZXJlTWF0Y2giLCJ3aGVyZVJhdyIsIlN0cmluZyIsIndoZXJlR3JvdXAiLCJidWlsZGVyIiwiZ3JvdXAiLCJXaGVyZUdyb3VwIiwib3JXaGVyZUdyb3VwIiwib3JXaGVyZSIsIm9yZGVyQnkiLCJkaXJlY3Rpb24iLCJsaW1pdCIsIm9mZnNldCIsImdyb3VwQnkiLCJjb2x1bW5zIiwiaGF2aW5nIiwiY29uZGl0aW9ucyIsInRoZW4iLCJvbmZ1bGZpbGxlZCIsIm9ucmVqZWN0ZWQiLCJ0IiwidG9RdWVyeSIsImNhdGNoIiwiZmluYWxseSIsIm9uZmluYWxseSIsImZpcnN0IiwiUmVzb2x2ZWRQdXJpIiwicGx1Y2siLCJpbnNlcnQiLCJkYXRhIiwidXBkYXRlIiwiaW5jcmVtZW50IiwiZGVjcmVtZW50IiwiZGVsZXRlIiwiZGVidWciLCJjb25zb2xlIiwibG9nIiwiY3lhbiIsInllbGxvdyIsImZvcm1hdFNRTCIsInVuZm9ybWF0dGVkIiwia2V5d29yZHMiLCJmb3JtYXR0ZWQiLCJmb3JFYWNoIiwia2V5d29yZCIsInJlZ2V4IiwiUmVnRXhwIiwicmVwbGFjZSIsInRvVXBwZXJDYXNlIiwibWFqb3JDbGF1c2VzIiwiY2xhdXNlIiwibGluZXMiLCJzcGxpdCIsImluZGVudGVkTGluZXMiLCJpbmRlbnRMZXZlbCIsImxpbmUiLCJ0cmltbWVkTGluZSIsInRyaW0iLCJjbG9zaW5nUGFyZW5zIiwibWF0Y2giLCJvcGVuaW5nUGFyZW5zIiwiTWF0aCIsImluZGVudCIsInJlcGVhdCIsInNsaWNlIiwic3ViQnVpbGRlciIsInN1Ykdyb3VwIiwib24iLCJvck9uIl0sIm1hcHBpbmdzIjoiQUFlQSxPQUFPQSxXQUFXLFFBQVE7QUFDMUIsT0FBT0MsWUFBWSxTQUFTO0FBQzVCLFNBQVNDLEtBQUssUUFBUSxvQkFBaUI7QUFFdkMsT0FBTyxNQUFNQzs7SUFDSEMsVUFBNkI7SUFRckMsWUFDRSxBQUFPQyxJQUFVLEVBQ2pCQyxlQUFvQixDQUNwQjthQUZPRCxPQUFBQTtRQUdQLElBQUksT0FBT0Msb0JBQW9CLFVBQVU7WUFDdkMsZ0NBQWdDO1lBQ2hDLElBQUksQ0FBQ0YsU0FBUyxHQUFHLElBQUksQ0FBQ0MsSUFBSSxDQUFDQyxpQkFBaUJDLElBQUksQ0FBQ0Q7UUFDbkQsT0FBTyxJQUFJLE9BQU9BLG9CQUFvQixVQUFVO1lBQzlDLE1BQU1FLFVBQVVDLE9BQU9ELE9BQU8sQ0FBQ0Y7WUFDL0IsSUFBSUUsUUFBUUUsTUFBTSxLQUFLLEdBQUc7Z0JBQ3hCLE1BQU0sSUFBSUMsTUFBTTtZQUNsQjtZQUNBVixPQUFPTyxPQUFPLENBQUMsRUFBRTtZQUNqQixNQUFNLENBQUNJLE9BQU9DLEtBQUssR0FBR0wsT0FBTyxDQUFDLEVBQUU7WUFDaEMsSUFBSSxPQUFPSyxTQUFTLFVBQVU7Z0JBQzVCLElBQUksQ0FBQ1QsU0FBUyxHQUFHLElBQUksQ0FBQ0MsSUFBSSxDQUFDUSxNQUFNTixJQUFJLENBQUM7b0JBQUUsQ0FBQ0ssTUFBTSxFQUFFQztnQkFBSztZQUN4RCxPQUFPLElBQUlBLGdCQUFnQlYsTUFBTTtnQkFDL0IsTUFBTVcsa0JBQWtCRCxLQUFLRSxHQUFHO2dCQUNoQyxJQUFJLENBQUNYLFNBQVMsR0FBRyxJQUFJLENBQUNDLElBQUksQ0FBQ0UsSUFBSSxDQUFDTyxnQkFBZ0JFLEVBQUUsQ0FBQ0o7WUFDckQsT0FBTztnQkFDTCxNQUFNLElBQUlELE1BQU07WUFDbEI7UUFDRixPQUFPO1lBQ0wsTUFBTSxJQUFJQSxNQUFNO1FBQ2xCO0lBQ0Y7SUFFQSx5Q0FBeUM7SUFDekMsT0FBT00sTUFBTUMsU0FBaUIsR0FBRyxFQUEyQjtRQUMxRCxPQUFPO1lBQ0xDLE9BQU87WUFDUEMsU0FBUztZQUNUQyxNQUFNLENBQUMsTUFBTSxFQUFFSCxPQUFPLENBQUMsQ0FBQztRQUMxQjtJQUNGO0lBQ0EsT0FBT0ksSUFBSUosTUFBYyxFQUEyQjtRQUNsRCxPQUFPO1lBQ0xDLE9BQU87WUFDUEMsU0FBUztZQUNUQyxNQUFNLENBQUMsSUFBSSxFQUFFSCxPQUFPLENBQUMsQ0FBQztRQUN4QjtJQUNGO0lBQ0EsT0FBT0ssSUFBSUwsTUFBYyxFQUEyQjtRQUNsRCxPQUFPO1lBQ0xDLE9BQU87WUFDUEMsU0FBUztZQUNUQyxNQUFNLENBQUMsSUFBSSxFQUFFSCxPQUFPLENBQUMsQ0FBQztRQUN4QjtJQUNGO0lBQ0EsT0FBT00sSUFBSU4sTUFBYyxFQUEyQjtRQUNsRCxPQUFPO1lBQ0xDLE9BQU87WUFDUEMsU0FBUztZQUNUQyxNQUFNLENBQUMsSUFBSSxFQUFFSCxPQUFPLENBQUMsQ0FBQztRQUN4QjtJQUNGO0lBQ0EsT0FBT08sSUFBSVAsTUFBYyxFQUEyQjtRQUNsRCxPQUFPO1lBQ0xDLE9BQU87WUFDUEMsU0FBUztZQUNUQyxNQUFNLENBQUMsSUFBSSxFQUFFSCxPQUFPLENBQUMsQ0FBQztRQUN4QjtJQUNGO0lBQ0EsT0FBT1EsT0FBTyxHQUFHQyxJQUFjLEVBQTJCO1FBQ3hELE9BQU87WUFDTFIsT0FBTztZQUNQQyxTQUFTO1lBQ1RDLE1BQU0sQ0FBQyxPQUFPLEVBQUVNLEtBQUtDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUNwQztJQUNGO0lBQ0EsT0FBT0MsTUFBTVgsTUFBYyxFQUEyQjtRQUNwRCxPQUFPO1lBQ0xDLE9BQU87WUFDUEMsU0FBUztZQUNUQyxNQUFNLENBQUMsTUFBTSxFQUFFSCxPQUFPLENBQUMsQ0FBQztRQUMxQjtJQUNGO0lBQ0EsT0FBT1ksTUFBTVosTUFBYyxFQUEyQjtRQUNwRCxPQUFPO1lBQ0xDLE9BQU87WUFDUEMsU0FBUztZQUNUQyxNQUFNLENBQUMsTUFBTSxFQUFFSCxPQUFPLENBQUMsQ0FBQztRQUMxQjtJQUNGO0lBRUEsMkJBQTJCO0lBQzNCLE9BQU9hLFVBQVVDLEdBQVcsRUFBMkI7UUFDckQsT0FBTztZQUFFYixPQUFPO1lBQWtCQyxTQUFTO1lBQVVDLE1BQU1XO1FBQUk7SUFDakU7SUFDQSxPQUFPQyxVQUFVRCxHQUFXLEVBQTJCO1FBQ3JELE9BQU87WUFBRWIsT0FBTztZQUFrQkMsU0FBUztZQUFVQyxNQUFNVztRQUFJO0lBQ2pFO0lBQ0EsT0FBT0UsV0FBV0YsR0FBVyxFQUE0QjtRQUN2RCxPQUFPO1lBQUViLE9BQU87WUFBa0JDLFNBQVM7WUFBV0MsTUFBTVc7UUFBSTtJQUNsRTtJQUNBLE9BQU9HLFFBQVFILEdBQVcsRUFBeUI7UUFDakQsT0FBTztZQUFFYixPQUFPO1lBQWtCQyxTQUFTO1lBQVFDLE1BQU1XO1FBQUk7SUFDL0Q7SUFFQSxxQkFBcUI7SUFDckJJLE9BQ0VDLFNBQWtCLEVBQzJDO1FBQzdELE1BQU1DLGdCQUF1QyxFQUFFO1FBRS9DLEtBQUssTUFBTSxDQUFDMUIsT0FBTzJCLGlCQUFpQixJQUFJOUIsT0FBT0QsT0FBTyxDQUFDNkIsV0FBWTtZQUNqRSxJQUNFLE9BQU9FLHFCQUFxQixZQUM1QkEsaUJBQWlCcEIsS0FBSyxLQUFLLGtCQUMzQjtnQkFDQSxhQUFhO2dCQUNibUIsY0FBY0UsSUFBSSxDQUNoQixJQUFJLENBQUNuQyxJQUFJLENBQUNVLEdBQUcsQ0FBQyxHQUFHd0IsaUJBQWlCbEIsSUFBSSxDQUFDLElBQUksRUFBRVQsT0FBTztZQUV4RCxPQUFPO2dCQUNMLFlBQVk7Z0JBQ1osTUFBTTZCLGFBQWFGO2dCQUNuQixJQUFJM0IsVUFBVTZCLFlBQVk7b0JBQ3hCLDJCQUEyQjtvQkFDM0JILGNBQWNFLElBQUksQ0FBQ0M7Z0JBQ3JCLE9BQU87b0JBQ0wsV0FBVztvQkFDWEgsY0FBY0UsSUFBSSxDQUFDLEdBQUdDLFdBQVcsSUFBSSxFQUFFN0IsT0FBTztnQkFDaEQ7WUFDRjtRQUNGO1FBRUEsSUFBSSxDQUFDUixTQUFTLENBQUNnQyxNQUFNLENBQUNFO1FBQ3RCLE9BQU8sSUFBSTtJQUNiO0lBRUEsbURBQW1EO0lBQ25ESSxhQUNFTCxTQUFrQixFQUNxRDtRQUN2RSxPQUFPLElBQUksQ0FBQ0QsTUFBTSxDQUFDQztJQUNyQjtJQUVBLFdBQVc7SUFDWE0sWUFBa0I7UUFDaEIsSUFBSSxDQUFDdkMsU0FBUyxDQUFDZ0MsTUFBTSxDQUFDO1FBQ3RCLE9BQU8sSUFBSTtJQUNiO0lBcURBLGFBQWE7SUFDYlIsS0FBS3RCLGVBQW9CLEVBQUUsR0FBR3FCLElBQVcsRUFBTztRQUM5QyxPQUFPLElBQUksQ0FBQ2lCLFlBQVksQ0FBQyxRQUFRdEMsb0JBQW9CcUI7SUFDdkQ7SUFxREEsa0JBQWtCO0lBQ2xCa0IsU0FBU3ZDLGVBQW9CLEVBQUUsR0FBR3FCLElBQVcsRUFBTztRQUNsRCxPQUFPLElBQUksQ0FBQ2lCLFlBQVksQ0FBQyxZQUFZdEMsb0JBQW9CcUI7SUFDM0Q7SUFFQWlCLGFBQ0VFLFFBQTZCLEVBQzdCeEMsZUFBb0IsRUFDcEIsR0FBR3FCLElBQVcsRUFDUjtRQUNOLElBQUksT0FBT3JCLG9CQUFvQixVQUFVO1lBQ3ZDLDZCQUE2QjtZQUM3QixNQUFNeUMsWUFBWXpDO1lBRWxCLElBQUlxQixLQUFLakIsTUFBTSxLQUFLLEtBQUssT0FBT2lCLElBQUksQ0FBQyxFQUFFLEtBQUssWUFBWTtnQkFDdEQsMEJBQTBCO2dCQUMxQixNQUFNcUIsV0FBV3JCLElBQUksQ0FBQyxFQUFFO2dCQUN4QixJQUFJLENBQUN2QixTQUFTLENBQUMwQyxTQUFTLENBQUNDLFdBQVcsQ0FBQ0U7b0JBQ25DRCxTQUFTLElBQUlFLGdCQUFnQkQ7Z0JBQy9CO1lBQ0YsT0FBTztnQkFDTCw2QkFBNkI7Z0JBQzdCLE1BQU0sQ0FBQ0UsTUFBTUMsTUFBTSxHQUFHekI7Z0JBQ3RCLElBQUksQ0FBQ3ZCLFNBQVMsQ0FBQzBDLFNBQVMsQ0FBQ0MsV0FBV0ksTUFBTUM7WUFDNUM7UUFDRixPQUFPLElBQUksT0FBTzlDLG9CQUFvQixVQUFVO1lBQzlDLDBFQUEwRTtZQUMxRSxNQUFNRSxVQUFVQyxPQUFPRCxPQUFPLENBQUNGO1lBQy9CLElBQUlFLFFBQVFFLE1BQU0sS0FBSyxHQUFHO2dCQUN4QixNQUFNLElBQUlDLE1BQU07WUFDbEI7WUFDQVYsT0FBT08sT0FBTyxDQUFDLEVBQUU7WUFDakIsTUFBTSxDQUFDLENBQUNJLE9BQU9DLEtBQUssQ0FBQyxHQUFHTDtZQUV4QixJQUFJLE9BQU9LLFNBQVMsVUFBVTtnQkFDNUIsaUNBQWlDO2dCQUNqQyxJQUFJYyxLQUFLakIsTUFBTSxLQUFLLEtBQUssT0FBT2lCLElBQUksQ0FBQyxFQUFFLEtBQUssWUFBWTtvQkFDdEQsV0FBVztvQkFDWCxNQUFNcUIsV0FBV3JCLElBQUksQ0FBQyxFQUFFO29CQUN4QixJQUFJLENBQUN2QixTQUFTLENBQUMwQyxTQUFTLENBQUM7d0JBQUUsQ0FBQ2xDLE1BQU0sRUFBRUM7b0JBQUssR0FBRyxDQUFDb0M7d0JBQzNDRCxTQUFTLElBQUlFLGdCQUFnQkQ7b0JBQy9CO2dCQUNGLE9BQU87b0JBQ0wsU0FBUztvQkFDVCxNQUFNLENBQUNFLE1BQU1DLE1BQU0sR0FBR3pCO29CQUN0QixJQUFJLENBQUN2QixTQUFTLENBQUMwQyxTQUFTLENBQUM7d0JBQUUsQ0FBQ2xDLE1BQU0sRUFBRUM7b0JBQUssR0FBR3NDLE1BQU1DO2dCQUNwRDtZQUNGLE9BQU8sSUFBSXZDLGdCQUFnQlYsTUFBTTtnQkFDL0Isb0NBQW9DO2dCQUNwQyxJQUFJd0IsS0FBS2pCLE1BQU0sS0FBSyxLQUFLLE9BQU9pQixJQUFJLENBQUMsRUFBRSxLQUFLLFlBQVk7b0JBQ3RELFdBQVc7b0JBQ1gsTUFBTXFCLFdBQVdyQixJQUFJLENBQUMsRUFBRTtvQkFDeEIsSUFBSSxDQUFDdkIsU0FBUyxDQUFDMEMsU0FBUyxDQUFDakMsS0FBS0UsR0FBRyxHQUFHQyxFQUFFLENBQUNKLFFBQVEsQ0FBQ3FDO3dCQUM5Q0QsU0FBUyxJQUFJRSxnQkFBZ0JEO29CQUMvQjtnQkFDRixPQUFPO29CQUNMLFNBQVM7b0JBQ1QsTUFBTSxDQUFDRSxNQUFNQyxNQUFNLEdBQUd6QjtvQkFDdEIsSUFBSSxDQUFDdkIsU0FBUyxDQUFDMEMsU0FBUyxDQUFDakMsS0FBS0UsR0FBRyxHQUFHQyxFQUFFLENBQUNKLFFBQVF1QyxNQUFNQztnQkFDdkQ7WUFDRixPQUFPO2dCQUNMLE1BQU0sSUFBSXpDLE1BQU07WUFDbEI7UUFDRixPQUFPO1lBQ0wsTUFBTSxJQUFJQSxNQUFNO1FBQ2xCO1FBRUEsT0FBTyxJQUFJO0lBQ2I7SUFlQSxtREFBbUQ7SUFDbkQwQyxNQUFNQyxrQkFBdUIsRUFBRUMsZUFBcUIsRUFBRUMsS0FBVyxFQUFRO1FBQ3ZFLElBQUksT0FBT0YsdUJBQXVCLFVBQVU7WUFDMUMsSUFBSSxDQUFDbEQsU0FBUyxDQUFDaUQsS0FBSyxDQUFDQztRQUN2QixPQUFPLElBQUlHLFVBQVUvQyxNQUFNLEtBQUssR0FBRztZQUNqQyxJQUFJNkMsb0JBQW9CLE1BQU07Z0JBQzVCLElBQUksQ0FBQ25ELFNBQVMsQ0FBQ3NELFNBQVMsQ0FBQ0o7Z0JBQ3pCLE9BQU8sSUFBSTtZQUNiO1lBQ0EsSUFBSSxDQUFDbEQsU0FBUyxDQUFDaUQsS0FBSyxDQUFDQyxvQkFBb0JDO1FBQzNDLE9BQU8sSUFBSUUsVUFBVS9DLE1BQU0sS0FBSyxHQUFHO1lBQ2pDLElBQUk4QyxVQUFVLE1BQU07Z0JBQ2xCLElBQUlELG9CQUFvQixNQUFNO29CQUM1QixJQUFJLENBQUNuRCxTQUFTLENBQUN1RCxZQUFZLENBQUNMO29CQUM1QixPQUFPLElBQUk7Z0JBQ2IsT0FBTyxJQUFJQyxvQkFBb0IsS0FBSztvQkFDbEMsSUFBSSxDQUFDbkQsU0FBUyxDQUFDc0QsU0FBUyxDQUFDSjtvQkFDekIsT0FBTyxJQUFJO2dCQUNiO1lBQ0Y7WUFDQSxJQUFJLENBQUNsRCxTQUFTLENBQUNpRCxLQUFLLENBQUNDLG9CQUFvQkMsaUJBQWlCQztRQUM1RCxPQUFPO1lBQ0wsSUFBSSxDQUFDcEQsU0FBUyxDQUFDaUQsS0FBSyxDQUFDQztRQUN2QjtRQUNBLE9BQU8sSUFBSTtJQUNiO0lBRUEsV0FBVztJQUNYTSxRQUNFMUMsTUFBZSxFQUNmMkMsTUFBc0QsRUFDckI7UUFDakMsSUFBSSxDQUFDekQsU0FBUyxDQUFDd0QsT0FBTyxDQUFDMUMsUUFBUTJDO1FBQy9CLE9BQU8sSUFBSTtJQUNiO0lBRUEsZUFBZTtJQUNmQyxXQUNFNUMsTUFBZSxFQUNmMkMsTUFBc0QsRUFDckI7UUFDakMsSUFBSSxDQUFDekQsU0FBUyxDQUFDd0QsT0FBTyxDQUFDMUMsUUFBUTJDO1FBQy9CLE9BQU8sSUFBSTtJQUNiO0lBRUEsY0FBYztJQUNkRSxXQUNFN0MsTUFBZSxFQUNmc0MsS0FBYSxFQUNQO1FBQ04sSUFBSSxDQUFDcEQsU0FBUyxDQUFDNEQsUUFBUSxDQUFDLENBQUMsT0FBTyxFQUFFQyxPQUFPL0MsUUFBUSxhQUFhLENBQUMsRUFBRTtZQUFDc0M7U0FBTTtRQUN4RSxPQUFPLElBQUk7SUFDYjtJQUVBLGVBQWU7SUFDZlUsV0FBV2xCLFFBQTBDLEVBQVE7UUFDM0QsSUFBSSxDQUFDNUMsU0FBUyxDQUFDaUQsS0FBSyxDQUFDLENBQUNjO1lBQ3BCLE1BQU1DLFFBQVEsSUFBSUMsV0FBb0JGO1lBQ3RDbkIsU0FBU29CO1FBQ1g7UUFDQSxPQUFPLElBQUk7SUFDYjtJQUNBRSxhQUFhdEIsUUFBMEMsRUFBUTtRQUM3RCxJQUFJLENBQUM1QyxTQUFTLENBQUNtRSxPQUFPLENBQUMsQ0FBQ0o7WUFDdEIsTUFBTUMsUUFBUSxJQUFJQyxXQUFvQkY7WUFDdENuQixTQUFTb0I7UUFDWDtRQUNBLE9BQU8sSUFBSTtJQUNiO0lBT0FJLFFBQVF0RCxNQUFjLEVBQUV1RCxZQUE0QixLQUFLLEVBQVE7UUFDL0QsSUFBSSxDQUFDckUsU0FBUyxDQUFDb0UsT0FBTyxDQUFDdEQsUUFBUXVEO1FBQy9CLE9BQU8sSUFBSTtJQUNiO0lBRUEsYUFBYTtJQUNiQyxNQUFNekQsS0FBYSxFQUFRO1FBQ3pCLElBQUksQ0FBQ2IsU0FBUyxDQUFDc0UsS0FBSyxDQUFDekQ7UUFDckIsT0FBTyxJQUFJO0lBQ2I7SUFFQTBELE9BQU8xRCxLQUFhLEVBQVE7UUFDMUIsSUFBSSxDQUFDYixTQUFTLENBQUN1RSxNQUFNLENBQUMxRDtRQUN0QixPQUFPLElBQUk7SUFDYjtJQU1BMkQsUUFBUSxHQUFHQyxPQUFpQixFQUFRO1FBQ2xDLElBQUksQ0FBQ3pFLFNBQVMsQ0FBQ3dFLE9BQU8sSUFBS0M7UUFDM0IsT0FBTyxJQUFJO0lBQ2I7SUFTQSxZQUFZO0lBQ1pDLE9BQU8sR0FBR0MsVUFBaUIsRUFBUTtRQUNqQyxJQUFJQSxXQUFXckUsTUFBTSxLQUFLLEdBQUc7WUFDM0IsMEJBQTBCO1lBQzFCLElBQUksQ0FBQ04sU0FBUyxDQUFDMEUsTUFBTSxDQUFDQyxVQUFVLENBQUMsRUFBRTtRQUNyQyxPQUFPLElBQUlBLFdBQVdyRSxNQUFNLEtBQUssR0FBRztZQUNsQywyQkFBMkI7WUFDM0IsSUFBSSxDQUFDTixTQUFTLENBQUMwRSxNQUFNLENBQUNDLFVBQVUsQ0FBQyxFQUFFLEVBQUVBLFVBQVUsQ0FBQyxFQUFFLEVBQUVBLFVBQVUsQ0FBQyxFQUFFO1FBQ25FLE9BQU87WUFDTCxNQUFNLElBQUlwRSxNQUFNO1FBQ2xCO1FBQ0EsT0FBTyxJQUFJO0lBQ2I7SUFFQSx3QkFBd0I7SUFDeEJxRSxLQUNFQyxXQUVRLEVBQ1JDLFVBQXVFLEVBQ3pDO1FBQzlCaEYsTUFBTWlGLENBQUMsQ0FBQyxjQUFjLElBQUksQ0FBQ0MsT0FBTztRQUNsQyxPQUFPLElBQUksQ0FBQ2hGLFNBQVMsQ0FBQzRFLElBQUksQ0FBQ0MsYUFBb0JDO0lBQ2pEO0lBQ0FHLE1BQ0VILFVBQXVFLEVBQzFDO1FBQzdCLE9BQU8sSUFBSSxDQUFDOUUsU0FBUyxDQUFDaUYsS0FBSyxDQUFDSDtJQUM5QjtJQUNBSSxRQUFRQyxTQUErQixFQUFvQjtRQUN6RCxPQUFPLElBQUksQ0FBQ25GLFNBQVMsQ0FBQ2tGLE9BQU8sQ0FBQ0M7SUFDaEM7SUFFQSxTQUFTO0lBQ1RDLFFBQThDO1FBQzVDLElBQUksQ0FBQ3BGLFNBQVMsQ0FBQ29GLEtBQUs7UUFDcEIsT0FBTyxJQUFJQyxhQUFhLElBQUksQ0FBQ3JGLFNBQVM7SUFDeEM7SUFFQSw2QkFBNkI7SUFDN0JzRixNQUdFeEUsTUFBZSxFQU1mO1FBQ0EsSUFBSSxDQUFDZCxTQUFTLENBQUNzRixLQUFLLENBQUN4RTtRQUNyQixPQUFPLElBQUl1RSxhQUFhLElBQUksQ0FBQ3JGLFNBQVM7SUFDeEM7SUFFQSxTQUFTO0lBQ1R1RixPQUNFQyxJQUEyQyxFQUNaO1FBQy9CLElBQUksQ0FBQ3hGLFNBQVMsQ0FBQ3VGLE1BQU0sQ0FBQ0M7UUFDdEIsT0FBTyxJQUFJSCxhQUFhLElBQUksQ0FBQ3JGLFNBQVM7SUFDeEM7SUFFQSxTQUFTO0lBQ1R5RixPQUFPRCxJQUE2QixFQUFpQztRQUNuRSxJQUFJLENBQUN4RixTQUFTLENBQUN5RixNQUFNLENBQUNEO1FBQ3RCLE9BQU8sSUFBSUgsYUFBYSxJQUFJLENBQUNyRixTQUFTO0lBQ3hDO0lBRUEsWUFBWTtJQUNaMEYsVUFDRTVFLE1BQWUsRUFDZnNDLEtBQWEsRUFDZ0I7UUFDN0IsSUFBSUEsU0FBUyxHQUFHO1lBQ2QsTUFBTSxJQUFJN0MsTUFBTTtRQUNsQjtRQUNBLElBQUksQ0FBQ1AsU0FBUyxDQUFDMEYsU0FBUyxDQUFDNUUsUUFBUXNDO1FBQ2pDLE9BQU8sSUFBSWlDLGFBQWEsSUFBSSxDQUFDckYsU0FBUztJQUN4QztJQUNBLFlBQVk7SUFDWjJGLFVBQ0U3RSxNQUFlLEVBQ2ZzQyxLQUFhLEVBQ2dCO1FBQzdCLElBQUlBLFNBQVMsR0FBRztZQUNkLE1BQU0sSUFBSTdDLE1BQU07UUFDbEI7UUFDQSxJQUFJLENBQUNQLFNBQVMsQ0FBQzJGLFNBQVMsQ0FBQzdFLFFBQVFzQztRQUNqQyxPQUFPLElBQUlpQyxhQUFhLElBQUksQ0FBQ3JGLFNBQVM7SUFDeEM7SUFFQSxTQUFTO0lBQ1Q0RixTQUFzQztRQUNwQyxJQUFJLENBQUM1RixTQUFTLENBQUM0RixNQUFNO1FBQ3JCLE9BQU8sSUFBSVAsYUFBYSxJQUFJLENBQUNyRixTQUFTO0lBQ3hDO0lBRUEsV0FBVztJQUNYZ0YsVUFBa0I7UUFDaEIsT0FBTyxJQUFJLENBQUNoRixTQUFTLENBQUNnRixPQUFPO0lBQy9CO0lBRUEsZUFBZTtJQUNmYSxRQUFjO1FBQ1pDLFFBQVFDLEdBQUcsQ0FDVCxHQUFHbkcsTUFBTW9HLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxFQUFFcEcsTUFBTXFHLE1BQU0sQ0FBQyxJQUFJLENBQUNqQixPQUFPLEtBQUs7UUFFakUsT0FBTyxJQUFJO0lBQ2I7SUFFQWtCLFVBQVVDLFdBQW1CLEVBQVU7UUFDckMsYUFBYTtRQUNiLE1BQU1DLFdBQVc7WUFDZjtZQUNBO1lBQ0E7WUFDQTtZQUNBO1lBQ0E7WUFDQTtZQUNBO1lBQ0E7WUFDQTtZQUNBO1lBQ0E7WUFDQTtZQUNBO1lBQ0E7WUFDQTtZQUNBO1lBQ0E7WUFDQTtZQUNBO1lBQ0E7WUFDQTtZQUNBO1lBQ0E7WUFDQTtZQUNBO1lBQ0E7WUFDQTtZQUNBO1lBQ0E7WUFDQTtZQUNBO1lBQ0E7WUFDQTtZQUNBO1lBQ0E7WUFDQTtZQUNBO1lBQ0E7WUFDQTtZQUNBO1lBQ0E7WUFDQTtTQUNEO1FBRUQsSUFBSUMsWUFBWUY7UUFFaEIsZUFBZTtRQUNmQyxTQUFTRSxPQUFPLENBQUMsQ0FBQ0M7WUFDaEIsTUFBTUMsUUFBUSxJQUFJQyxPQUFPLENBQUMsR0FBRyxFQUFFRixRQUFRLEdBQUcsQ0FBQyxFQUFFO1lBQzdDRixZQUFZQSxVQUFVSyxPQUFPLENBQUNGLE9BQU9ELFFBQVFJLFdBQVc7UUFDMUQ7UUFFQSxpQkFBaUI7UUFDakIsTUFBTUMsZUFBZTtZQUNuQjtZQUNBO1lBQ0E7WUFDQTtZQUNBO1lBQ0E7WUFDQTtZQUNBO1NBQ0Q7UUFDREEsYUFBYU4sT0FBTyxDQUFDLENBQUNPO1lBQ3BCLE1BQU1MLFFBQVEsSUFBSUMsT0FBTyxDQUFDLEtBQUssRUFBRUksT0FBTyxLQUFLLENBQUMsRUFBRTtZQUNoRFIsWUFBWUEsVUFBVUssT0FBTyxDQUFDRixPQUFPLENBQUMsRUFBRSxFQUFFSyxPQUFPRixXQUFXLEdBQUcsQ0FBQyxDQUFDO1FBQ25FO1FBRUEsWUFBWTtRQUNaTixZQUFZQSxVQUFVSyxPQUFPLENBQzNCLHFEQUNBO1FBR0YsZ0JBQWdCO1FBQ2hCTCxZQUFZQSxVQUFVSyxPQUFPLENBQUMsb0JBQW9CO1FBRWxELGVBQWU7UUFDZixNQUFNSSxRQUFRVCxVQUFVVSxLQUFLLENBQUM7UUFDOUIsTUFBTUMsZ0JBQWdCLEVBQUU7UUFDeEIsSUFBSUMsY0FBYztRQUVsQixLQUFLLElBQUlDLFFBQVFKLE1BQU87WUFDdEIsTUFBTUssY0FBY0QsS0FBS0UsSUFBSTtZQUM3QixJQUFJLENBQUNELGFBQWE7WUFFbEIsd0JBQXdCO1lBQ3hCLE1BQU1FLGdCQUFnQixBQUFDRixDQUFBQSxZQUFZRyxLQUFLLENBQUMsVUFBVSxFQUFFLEFBQUQsRUFBR2hILE1BQU07WUFDN0QsTUFBTWlILGdCQUFnQixBQUFDSixDQUFBQSxZQUFZRyxLQUFLLENBQUMsVUFBVSxFQUFFLEFBQUQsRUFBR2hILE1BQU07WUFFN0QsSUFBSStHLGdCQUFnQixLQUFLRSxrQkFBa0IsR0FBRztnQkFDNUNOLGNBQWNPLEtBQUtwRyxHQUFHLENBQUMsR0FBRzZGLGNBQWNJO1lBQzFDO1lBRUEsYUFBYTtZQUNiLE1BQU1JLFNBQVMsS0FBS0MsTUFBTSxDQUFDVDtZQUMzQkQsY0FBYzVFLElBQUksQ0FBQ3FGLFNBQVNOO1lBRTVCLHdCQUF3QjtZQUN4QixJQUFJSSxnQkFBZ0JGLGVBQWU7Z0JBQ2pDSixlQUFlTSxnQkFBZ0JGO1lBQ2pDO1FBQ0Y7UUFFQSxPQUFPTCxjQUFjeEYsSUFBSSxDQUFDLE1BQU00RixJQUFJO0lBQ3RDO0lBRUEsbUJBQW1CO0lBQ25CekcsTUFBeUI7UUFDdkIsT0FBTyxJQUFJLENBQUNYLFNBQVM7SUFDdkI7QUFDRjtBQUVBLE9BQU8sTUFBTWlFOztJQUNYLFlBQVksQUFBUUYsT0FBMEIsQ0FBRTthQUE1QkEsVUFBQUE7SUFBNkI7SUFhakRkLE1BQU0sR0FBRzFCLElBQVcsRUFBdUI7UUFDekMsSUFBSSxDQUFDd0MsT0FBTyxDQUFDZCxLQUFLLENBQUMxQixJQUFJLENBQUMsRUFBRSxLQUFLQSxLQUFLb0csS0FBSyxDQUFDO1FBQzFDLE9BQU8sSUFBSTtJQUNiO0lBYUF4RCxRQUFRLEdBQUc1QyxJQUFXLEVBQXVCO1FBQzNDLElBQUksQ0FBQ3dDLE9BQU8sQ0FBQ0ksT0FBTyxDQUFDNUMsSUFBSSxDQUFDLEVBQUUsS0FBS0EsS0FBS29HLEtBQUssQ0FBQztRQUM1QyxPQUFPLElBQUk7SUFDYjtJQUlBN0QsV0FBV2xCLFFBQTBDLEVBQXVCO1FBQzFFLElBQUksQ0FBQ21CLE9BQU8sQ0FBQ2QsS0FBSyxDQUFDLENBQUMyRTtZQUNsQixNQUFNQyxXQUFXLElBQUk1RCxXQUFvQjJEO1lBQ3pDaEYsU0FBU2lGO1FBQ1g7UUFDQSxPQUFPLElBQUk7SUFDYjtJQUVBM0QsYUFDRXRCLFFBQTBDLEVBQ3JCO1FBQ3JCLElBQUksQ0FBQ21CLE9BQU8sQ0FBQ0ksT0FBTyxDQUFDLENBQUN5RDtZQUNwQixNQUFNQyxXQUFXLElBQUk1RCxXQUFvQjJEO1lBQ3pDaEYsU0FBU2lGO1FBQ1g7UUFDQSxPQUFPLElBQUk7SUFDYjtBQUNGO0FBRUEsT0FBTyxNQUFNL0U7O0lBSVgsWUFBWSxBQUFRRixRQUF5QixDQUFFO2FBQTNCQSxXQUFBQTtJQUE0QjtJQVloRCxhQUFhO0lBQ2JrRixHQUFHLEdBQUd2RyxJQUFXLEVBQVE7UUFDdkIsSUFBSSxDQUFDcUIsUUFBUSxDQUFDa0YsRUFBRSxJQUFLdkc7UUFDckIsT0FBTyxJQUFJO0lBQ2I7SUFZQSxZQUFZO0lBQ1p3RyxLQUFLLEdBQUd4RyxJQUFXLEVBQVE7UUFDekIsSUFBSSxDQUFDcUIsUUFBUSxDQUFDbUYsSUFBSSxJQUFLeEc7UUFDdkIsT0FBTyxJQUFJO0lBQ2I7QUFDRjtBQUVBOzs7QUFHQSxHQUNBLE9BQU8sTUFBTThEOztJQUNYLFlBQVksQUFBT3JGLFNBQTRCLENBQUU7YUFBOUJBLFlBQUFBO0lBQStCO0lBRWxEZ0YsVUFBa0I7UUFDaEIsT0FBTyxJQUFJLENBQUNoRixTQUFTLENBQUNnRixPQUFPO0lBQy9CO0lBRUFhLFFBQWM7UUFDWkMsUUFBUUMsR0FBRyxDQUNULEdBQUduRyxNQUFNb0csSUFBSSxDQUFDLGdCQUFnQixDQUFDLEVBQUVwRyxNQUFNcUcsTUFBTSxDQUFDLElBQUksQ0FBQ2pCLE9BQU8sS0FBSztRQUVqRSxPQUFPLElBQUk7SUFDYjtJQUVBSixLQUNFQyxXQUVRLEVBQ1JDLFVBQXVFLEVBQ3pDO1FBQzlCaEYsTUFBTWlGLENBQUMsQ0FBQyxjQUFjLElBQUksQ0FBQ0MsT0FBTztRQUNsQyxPQUFPLElBQUksQ0FBQ2hGLFNBQVMsQ0FBQzRFLElBQUksQ0FBQ0MsYUFBb0JDO0lBQ2pEO0lBQ0FHLE1BQ0VILFVBQXVFLEVBQ3hDO1FBQy9CLE9BQU8sSUFBSSxDQUFDOUUsU0FBUyxDQUFDaUYsS0FBSyxDQUFDSDtJQUM5QjtJQUNBSSxRQUFRQyxTQUErQixFQUFzQjtRQUMzRCxPQUFPLElBQUksQ0FBQ25GLFNBQVMsQ0FBQ2tGLE9BQU8sQ0FBQ0M7SUFDaEM7QUFDRiJ9
|