@openmrs/esm-app-shell 8.0.1-pre.3634 → 8.0.1-pre.3641

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.
Files changed (81) hide show
  1. package/.turbo/turbo-build.log +8 -8
  2. package/dist/{5eed73ad1fe58297.js.map → 252d189d3f90e5a1.js.map} +1 -1
  3. package/dist/{41bdf55745c102a0.js → 727bb9b657b275b8.js} +1 -1
  4. package/dist/{41bdf55745c102a0.js.map → 727bb9b657b275b8.js.map} +1 -1
  5. package/dist/index.html +1 -1
  6. package/dist/{openmrs.e934f1d9d22d022f.js → openmrs.7ae0818b15789c56.js} +1 -1
  7. package/dist/{openmrs.e934f1d9d22d022f.js.map → openmrs.7ae0818b15789c56.js.map} +1 -1
  8. package/dist/service-worker.js +1 -1
  9. package/lib/{1e175b579f4aa7f7.js → 46cfba320cf162c3.js} +3 -3
  10. package/lib/{0905c5f8cdb9169a.js → cbdd2de0ab9d4470.js} +1 -1
  11. package/lib/esm-help-menu-app/460.js +1 -1
  12. package/lib/esm-help-menu-app/460.js.map +1 -1
  13. package/lib/esm-help-menu-app/main.js +1 -1
  14. package/lib/esm-help-menu-app/openmrs-esm-help-menu-app.js +1 -1
  15. package/lib/esm-help-menu-app/openmrs-esm-help-menu-app.js.buildmanifest.json +5 -5
  16. package/lib/esm-help-menu-app/routes.json +1 -1
  17. package/lib/esm-implementer-tools-app/5460.js +1 -1
  18. package/lib/esm-implementer-tools-app/5460.js.map +1 -1
  19. package/lib/esm-implementer-tools-app/main.js +1 -1
  20. package/lib/esm-implementer-tools-app/openmrs-esm-implementer-tools-app.js +1 -1
  21. package/lib/esm-implementer-tools-app/openmrs-esm-implementer-tools-app.js.buildmanifest.json +5 -5
  22. package/lib/esm-implementer-tools-app/routes.json +1 -1
  23. package/lib/esm-login-app/14.js +1 -1
  24. package/lib/esm-login-app/14.js.map +1 -1
  25. package/lib/esm-login-app/main.js +1 -1
  26. package/lib/esm-login-app/openmrs-esm-login-app.js +1 -1
  27. package/lib/esm-login-app/openmrs-esm-login-app.js.buildmanifest.json +5 -5
  28. package/lib/esm-login-app/routes.json +1 -1
  29. package/lib/esm-offline-tools-app/5460.js +1 -1
  30. package/lib/esm-offline-tools-app/5460.js.map +1 -1
  31. package/lib/esm-offline-tools-app/main.js +1 -1
  32. package/lib/esm-offline-tools-app/openmrs-esm-offline-tools-app.js +1 -1
  33. package/lib/esm-offline-tools-app/openmrs-esm-offline-tools-app.js.buildmanifest.json +5 -5
  34. package/lib/esm-offline-tools-app/routes.json +1 -1
  35. package/lib/esm-primary-navigation-app/5460.js +1 -1
  36. package/lib/esm-primary-navigation-app/5460.js.map +1 -1
  37. package/lib/esm-primary-navigation-app/main.js +1 -1
  38. package/lib/esm-primary-navigation-app/openmrs-esm-primary-navigation-app.js +1 -1
  39. package/lib/esm-primary-navigation-app/openmrs-esm-primary-navigation-app.js.buildmanifest.json +5 -5
  40. package/lib/esm-primary-navigation-app/routes.json +1 -1
  41. package/lib/index.html +2 -2
  42. package/lib/openmrs.js +7 -7
  43. package/lib/service-worker.js +1 -1
  44. package/package.json +3 -3
  45. package/lib/esm-devtools-app/180.js +0 -2
  46. package/lib/esm-devtools-app/180.js.LICENSE.txt +0 -5
  47. package/lib/esm-devtools-app/180.js.map +0 -1
  48. package/lib/esm-devtools-app/185.js +0 -2
  49. package/lib/esm-devtools-app/185.js.LICENSE.txt +0 -5
  50. package/lib/esm-devtools-app/185.js.map +0 -1
  51. package/lib/esm-devtools-app/300.js +0 -1
  52. package/lib/esm-devtools-app/326.js +0 -2
  53. package/lib/esm-devtools-app/326.js.LICENSE.txt +0 -9
  54. package/lib/esm-devtools-app/326.js.map +0 -1
  55. package/lib/esm-devtools-app/460.js +0 -1
  56. package/lib/esm-devtools-app/460.js.map +0 -1
  57. package/lib/esm-devtools-app/523.js +0 -2
  58. package/lib/esm-devtools-app/523.js.LICENSE.txt +0 -39
  59. package/lib/esm-devtools-app/523.js.map +0 -1
  60. package/lib/esm-devtools-app/623.js +0 -2
  61. package/lib/esm-devtools-app/623.js.LICENSE.txt +0 -19
  62. package/lib/esm-devtools-app/623.js.map +0 -1
  63. package/lib/esm-devtools-app/723.js +0 -2
  64. package/lib/esm-devtools-app/723.js.LICENSE.txt +0 -35
  65. package/lib/esm-devtools-app/723.js.map +0 -1
  66. package/lib/esm-devtools-app/770.js +0 -2
  67. package/lib/esm-devtools-app/770.js.LICENSE.txt +0 -14
  68. package/lib/esm-devtools-app/770.js.map +0 -1
  69. package/lib/esm-devtools-app/907.js +0 -1
  70. package/lib/esm-devtools-app/907.js.map +0 -1
  71. package/lib/esm-devtools-app/929.js +0 -1
  72. package/lib/esm-devtools-app/929.js.map +0 -1
  73. package/lib/esm-devtools-app/939.js +0 -1
  74. package/lib/esm-devtools-app/939.js.map +0 -1
  75. package/lib/esm-devtools-app/main.js +0 -1
  76. package/lib/esm-devtools-app/main.js.map +0 -1
  77. package/lib/esm-devtools-app/openmrs-esm-devtools-app.js +0 -1
  78. package/lib/esm-devtools-app/openmrs-esm-devtools-app.js.buildmanifest.json +0 -469
  79. package/lib/esm-devtools-app/openmrs-esm-devtools-app.js.map +0 -1
  80. package/lib/esm-devtools-app/routes.json +0 -1
  81. /package/dist/{5eed73ad1fe58297.js → 252d189d3f90e5a1.js} +0 -0
@@ -155,7 +155,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
155
155
  \**********************************************************************/
156
156
  /***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
157
157
 
158
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ clearConfigErrors: () => (/* binding */ clearConfigErrors),\n/* harmony export */ defineConfigSchema: () => (/* binding */ defineConfigSchema),\n/* harmony export */ defineExtensionConfigSchema: () => (/* binding */ defineExtensionConfigSchema),\n/* harmony export */ getConfig: () => (/* binding */ getConfig),\n/* harmony export */ getTranslationOverrides: () => (/* binding */ getTranslationOverrides),\n/* harmony export */ processConfig: () => (/* binding */ processConfig),\n/* harmony export */ provide: () => (/* binding */ provide),\n/* harmony export */ registerModuleLoad: () => (/* binding */ registerModuleLoad),\n/* harmony export */ registerModuleWithConfigSystem: () => (/* binding */ registerModuleWithConfigSystem),\n/* harmony export */ registerTranslationNamespace: () => (/* binding */ registerTranslationNamespace),\n/* harmony export */ resetConfigSystem: () => (/* binding */ resetConfigSystem)\n/* harmony export */ });\n/* harmony import */ var ramda__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ramda */ \"../../../node_modules/ramda/es/equals.js\");\n/* harmony import */ var ramda__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ramda */ \"../../../node_modules/ramda/es/mergeDeepRight.js\");\n/* harmony import */ var ramda__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ramda */ \"../../../node_modules/ramda/es/omit.js\");\n/* harmony import */ var ramda__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ramda */ \"../../../node_modules/ramda/es/clone.js\");\n/* harmony import */ var ramda__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ramda */ \"../../../node_modules/ramda/es/reduce.js\");\n/* harmony import */ var _types_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../types.js */ \"../../framework/esm-config/dist/types.js\");\n/* harmony import */ var _validators_type_validators_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../validators/type-validators.js */ \"../../framework/esm-config/dist/validators/type-validators.js\");\n/* harmony import */ var _validators_validator_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../validators/validator.js */ \"../../framework/esm-config/dist/validators/validator.js\");\n/* harmony import */ var _state_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./state.js */ \"../../framework/esm-config/dist/module-config/state.js\");\n/** @module @category Config */ \n\n\n\n\n/**\n * Store setup\n *\n *\n * Set up stores and subscriptions so that inputs get processed appropriately.\n *\n * There are *input* stores and *output* stores. The *input* stores\n * are configInternalStore, temporaryConfigStore, and configExtensionStore. The\n * output stores are set in the `compute...` functions. They are the module\n * config stores, the extension slot config stores (by module), the extension\n * config stores, and the implementer tools config store.\n *\n * This code sets up the subscriptions so that when an input store changes,\n * the correct set of output stores are updated.\n *\n * All `compute...` functions except `computeExtensionConfigs` are pure\n * (or are supposed to be), other than the fact that they all `setState`\n * store values at the end. `computeExtensionConfigs` calls `getGlobalStore`,\n * which creates stores.\n */ // Store unsubscribe functions to allow cleanup (e.g., in tests or hot module reloading)\nconst configSubscriptions = [];\n/**\n * Recomputes all configuration derived stores based on current state of input stores.\n * Called whenever any input store (configInternalStore, temporaryConfigStore, configExtensionStore) changes.\n */ function recomputeAllConfigs() {\n const configState = _state_js__WEBPACK_IMPORTED_MODULE_3__.configInternalStore.getState();\n const tempConfigState = _state_js__WEBPACK_IMPORTED_MODULE_3__.temporaryConfigStore.getState();\n const extensionState = _state_js__WEBPACK_IMPORTED_MODULE_3__.configExtensionStore.getState();\n computeModuleConfig(configState, tempConfigState);\n computeImplementerToolsConfig(configState, tempConfigState);\n computeExtensionSlotConfigs(configState, tempConfigState);\n computeExtensionConfigs(configState, extensionState, tempConfigState);\n}\nfunction setupConfigSubscriptions() {\n // Initial computation\n recomputeAllConfigs();\n // Subscribe to all input stores with a single handler\n // This ensures we only recompute once even if multiple stores change simultaneously\n configSubscriptions.push(_state_js__WEBPACK_IMPORTED_MODULE_3__.configInternalStore.subscribe(recomputeAllConfigs));\n configSubscriptions.push(_state_js__WEBPACK_IMPORTED_MODULE_3__.temporaryConfigStore.subscribe(recomputeAllConfigs));\n configSubscriptions.push(_state_js__WEBPACK_IMPORTED_MODULE_3__.configExtensionStore.subscribe(recomputeAllConfigs));\n}\n// Set up subscriptions at module load time\nsetupConfigSubscriptions();\nfunction computeModuleConfig(state, tempState) {\n for (let moduleName of Object.keys(state.schemas)){\n // At this point the schema could be either just the implicit schema or the actually\n // defined schema. We run with just the implicit schema because we want to populate\n // the config store with the translation overrides as soon as possible. In fact, the\n // translation system will throw for Suspense until the translation overrides are\n // available, which as of this writing blocks the schema definition from occurring\n // for modules loaded based on their extensions.\n const moduleStore = (0,_state_js__WEBPACK_IMPORTED_MODULE_3__.getConfigStore)(moduleName);\n let newState;\n if (state.moduleLoaded[moduleName]) {\n const config = getConfigForModule(moduleName, state, tempState);\n newState = {\n translationOverridesLoaded: true,\n loaded: true,\n config\n };\n } else {\n const config = getConfigForModuleImplicitSchema(moduleName, state, tempState);\n newState = {\n translationOverridesLoaded: true,\n loaded: false,\n config\n };\n }\n moduleStore.setState(newState);\n }\n}\nfunction computeExtensionSlotConfigs(state, tempState) {\n const slotConfigs = getExtensionSlotConfigs(state, tempState);\n const newSlotStoreEntries = Object.fromEntries(Object.entries(slotConfigs).map(([slotName, config])=>[\n slotName,\n {\n loaded: true,\n config\n }\n ]));\n const slotStore = (0,_state_js__WEBPACK_IMPORTED_MODULE_3__.getExtensionSlotsConfigStore)();\n const oldState = slotStore.getState();\n const newState = {\n slots: {\n ...oldState.slots,\n ...newSlotStoreEntries\n }\n };\n if (!(0,ramda__WEBPACK_IMPORTED_MODULE_4__[\"default\"])(oldState.slots, newState.slots)) {\n slotStore.setState(newState);\n }\n}\nfunction computeImplementerToolsConfig(state, tempConfigState) {\n const oldState = _state_js__WEBPACK_IMPORTED_MODULE_3__.implementerToolsConfigStore.getState();\n const config = getImplementerToolsConfig(state, tempConfigState);\n const newState = {\n config\n };\n // Use deep equality on the actual config content, not the wrapper object\n if (!(0,ramda__WEBPACK_IMPORTED_MODULE_4__[\"default\"])(oldState.config, newState.config)) {\n _state_js__WEBPACK_IMPORTED_MODULE_3__.implementerToolsConfigStore.setState(newState);\n }\n}\nfunction computeExtensionConfigs(configState, extensionState, tempConfigState) {\n const configs = {};\n // We assume that the module schema has already been defined, since the extension\n // it contains is mounted.\n for (let extension of extensionState.mountedExtensions){\n const config = computeExtensionConfig(extension.slotModuleName, extension.extensionModuleName, extension.slotName, extension.extensionId, configState, tempConfigState);\n if (!configs[extension.slotName]) {\n configs[extension.slotName] = {};\n }\n configs[extension.slotName][extension.extensionId] = {\n config,\n loaded: true\n };\n }\n const extensionsConfigStore = (0,_state_js__WEBPACK_IMPORTED_MODULE_3__.getExtensionsConfigStore)();\n const oldState = extensionsConfigStore.getState();\n const newState = {\n configs\n };\n // Use deep equality to only update if configs actually changed\n if (!(0,ramda__WEBPACK_IMPORTED_MODULE_4__[\"default\"])(oldState.configs, newState.configs)) {\n extensionsConfigStore.setState(newState);\n }\n}\n/*\n * API\n *\n */ /**\n * This defines a configuration schema for a module. The schema tells the\n * configuration system how the module can be configured. It specifies\n * what makes configuration valid or invalid.\n *\n * See [Configuration System](https://o3-docs.openmrs.org/docs/configuration-system)\n * for more information about defining a config schema.\n *\n * @param moduleName Name of the module the schema is being defined for. Generally\n * should be the one in which the `defineConfigSchema` call takes place.\n * @param schema The config schema for the module\n */ function defineConfigSchema(moduleName, schema) {\n validateConfigSchema(moduleName, schema);\n const enhancedSchema = (0,ramda__WEBPACK_IMPORTED_MODULE_5__[\"default\"])(schema, implicitConfigSchema);\n _state_js__WEBPACK_IMPORTED_MODULE_3__.configInternalStore.setState((state)=>({\n ...state,\n schemas: {\n ...state.schemas,\n [moduleName]: enhancedSchema\n },\n moduleLoaded: {\n ...state.moduleLoaded,\n [moduleName]: true\n }\n }));\n}\n/**\n * This alerts the configuration system that a module exists. This allows config to be\n * processed, while still allowing the extension system to know whether the module has\n * actually had its front bundle executed yet.\n *\n * This should only be used in esm-app-shell.\n *\n * @internal\n * @param moduleName\n */ function registerModuleWithConfigSystem(moduleName) {\n _state_js__WEBPACK_IMPORTED_MODULE_3__.configInternalStore.setState((state)=>({\n ...state,\n schemas: {\n ...state.schemas,\n [moduleName]: implicitConfigSchema\n }\n }));\n}\n/**\n * This alerts the configuration system that a module has been loaded.\n *\n * This should only be used in esm-app-shell.\n *\n * @internal\n * @param moduleName\n */ function registerModuleLoad(moduleName) {\n _state_js__WEBPACK_IMPORTED_MODULE_3__.configInternalStore.setState((state)=>({\n ...state,\n moduleLoaded: {\n ...state.moduleLoaded,\n [moduleName]: true\n }\n }));\n}\n/**\n * This allows the config system to support translation overrides for namespaces that\n * do not correspond to modules.\n *\n * This should only be used in esm-app-shell.\n *\n * @internal\n * @param namespace\n */ function registerTranslationNamespace(namespace) {\n _state_js__WEBPACK_IMPORTED_MODULE_3__.configInternalStore.setState((state)=>({\n ...state,\n schemas: {\n ...state.schemas,\n [namespace]: translationOverridesSchema\n }\n }));\n}\n/**\n * This defines a configuration schema for an extension. When a schema is defined\n * for an extension, that extension will receive the configuration corresponding\n * to that schema, rather than the configuration corresponding to the module\n * in which it is defined.\n *\n * The schema tells the configuration system how the module can be configured.\n * It specifies what makes configuration valid or invalid.\n *\n * See [Configuration System](https://o3-docs.openmrs.org/docs/configuration-system)\n * for more information about defining a config schema.\n *\n * @param extensionName Name of the extension the schema is being defined for.\n * Should match the `name` of one of the `extensions` entries being returned\n * by `setupOpenMRS`.\n * @param schema The config schema for the extension\n */ function defineExtensionConfigSchema(extensionName, schema) {\n validateConfigSchema(extensionName, schema);\n const enhancedSchema = (0,ramda__WEBPACK_IMPORTED_MODULE_5__[\"default\"])(schema, implicitConfigSchema);\n const state = _state_js__WEBPACK_IMPORTED_MODULE_3__.configInternalStore.getState();\n if (state.schemas[extensionName]) {\n console.error(`Config schema for extension ${extensionName} already exists. If there are multiple extensions with this same name, one will probably crash.`);\n }\n _state_js__WEBPACK_IMPORTED_MODULE_3__.configInternalStore.setState((state)=>({\n ...state,\n schemas: {\n ...state.schemas,\n [extensionName]: enhancedSchema\n }\n }));\n}\nfunction provide(config, sourceName = 'provided') {\n _state_js__WEBPACK_IMPORTED_MODULE_3__.configInternalStore.setState((state)=>({\n ...state,\n providedConfigs: [\n ...state.providedConfigs,\n {\n source: sourceName,\n config\n }\n ]\n }));\n}\n/**\n * A promise-based way to access the config as soon as it is fully loaded.\n * If it is already loaded, resolves the config in its present state.\n *\n * This is a useful function if you need to get the config in the course\n * of the execution of a function.\n *\n * @param moduleName The name of the module for which to look up the config\n */ function getConfig(moduleName) {\n return new Promise((resolve)=>{\n const store = (0,_state_js__WEBPACK_IMPORTED_MODULE_3__.getConfigStore)(moduleName);\n function update(state) {\n if (state.loaded && state.config) {\n const config = (0,ramda__WEBPACK_IMPORTED_MODULE_6__[\"default\"])([\n 'Display conditions',\n 'Translation overrides'\n ], state.config);\n resolve(config);\n if (unsubscribe) {\n unsubscribe();\n }\n }\n }\n update(store.getState());\n const unsubscribe = store.subscribe(update);\n });\n}\n/** @internal */ function getTranslationOverrides(moduleName, slotName, extensionId) {\n const promises = [\n new Promise((resolve)=>{\n const configStore = (0,_state_js__WEBPACK_IMPORTED_MODULE_3__.getConfigStore)(moduleName);\n function update(state) {\n if (state.translationOverridesLoaded && state.config) {\n const translationOverrides = state.config['Translation overrides'] ?? {};\n resolve(translationOverrides);\n if (unsubscribe) {\n unsubscribe();\n }\n }\n }\n update(configStore.getState());\n const unsubscribe = configStore.subscribe(update);\n })\n ];\n if (slotName && extensionId) {\n promises.push(new Promise((resolve)=>{\n const configStore = (0,_state_js__WEBPACK_IMPORTED_MODULE_3__.getExtensionConfig)(slotName, extensionId);\n function update(state) {\n if (state.loaded && state.config) {\n const translationOverrides = state.config['Translation overrides'] ?? {};\n resolve(translationOverrides);\n if (unsubscribe) {\n unsubscribe();\n }\n }\n }\n update(configStore.getState());\n const unsubscribe = configStore.subscribe(update);\n }));\n }\n return Promise.all(promises);\n}\n/**\n * Validate and interpolate defaults for `providedConfig` according to `schema`\n *\n * @param schema a configuration schema\n * @param providedConfig an object of config values (without the top-level module name)\n * @param keyPathContext a dot-deparated string which helps the user figure out where\n * the provided config came from\n * @internal\n */ function processConfig(schema, providedConfig, keyPathContext) {\n validateStructure(schema, providedConfig, keyPathContext);\n const config = setDefaults(schema, providedConfig);\n runAllValidatorsInConfigTree(schema, config, keyPathContext);\n return config;\n}\n/*\n * Helper functions\n *\n */ /**\n * Returns the configuration for an extension. This configuration is specific\n * to the slot in which it is mounted, and its ID within that slot.\n *\n * The schema for that configuration is the extension schema. If no extension\n * schema has been provided, the schema used is the schema of the module in\n * which the extension is defined.\n *\n * @param slotModuleName The name of the module which defines the extension slot\n * @param extensionModuleName The name of the module which defines the extension (and therefore the config schema)\n * @param slotName The name of the extension slot where the extension is mounted\n * @param extensionId The ID of the extension in its slot\n */ function computeExtensionConfig(slotModuleName, extensionModuleName, slotName, extensionId, configState, tempConfigState) {\n const extensionName = getExtensionNameFromId(extensionId);\n const extensionConfigSchema = configState.schemas[extensionName];\n const nameOfSchemaSource = extensionConfigSchema ? extensionName : extensionModuleName;\n const providedConfigs = getProvidedConfigs(configState, tempConfigState);\n const slotModuleConfig = mergeConfigsFor(slotModuleName, providedConfigs);\n const configOverride = slotModuleConfig?.extensionSlots?.[slotName]?.configure?.[extensionId] ?? {};\n const extensionConfig = mergeConfigsFor(nameOfSchemaSource, providedConfigs);\n const combinedConfig = mergeConfigs([\n extensionConfig,\n configOverride\n ]);\n const schema = extensionConfigSchema ?? configState.schemas[extensionModuleName];\n validateStructure(schema, combinedConfig, nameOfSchemaSource);\n const config = setDefaults(schema, combinedConfig);\n runAllValidatorsInConfigTree(schema, config, nameOfSchemaSource);\n delete config.extensionSlots;\n return config;\n}\nfunction getImplementerToolsConfig(configState, tempConfigState) {\n let result = getSchemaWithValuesAndSources((0,ramda__WEBPACK_IMPORTED_MODULE_7__[\"default\"])(configState.schemas));\n const configsAndSources = [\n ...configState.providedConfigs.map((c)=>[\n c.config,\n c.source\n ]),\n [\n tempConfigState.config,\n 'temporary config'\n ]\n ];\n for (let [config, source] of configsAndSources){\n result = mergeConfigs([\n result,\n createValuesAndSourcesTree(config, source)\n ]);\n }\n return result;\n}\nfunction getSchemaWithValuesAndSources(schema) {\n if (schema.hasOwnProperty('_default')) {\n return {\n ...schema,\n _value: schema._default,\n _source: 'default'\n };\n } else if (isOrdinaryObject(schema)) {\n return Object.keys(schema).reduce((obj, key)=>{\n obj[key] = getSchemaWithValuesAndSources(schema[key]);\n return obj;\n }, {});\n } else {\n // at this point, the schema is bad and an error will have been logged during schema validation\n return {};\n }\n}\nfunction createValuesAndSourcesTree(config, source) {\n if (isOrdinaryObject(config)) {\n return Object.keys(config).reduce((obj, key)=>{\n obj[key] = createValuesAndSourcesTree(config[key], source);\n return obj;\n }, {});\n } else {\n return {\n _value: config,\n _source: source\n };\n }\n}\nfunction getExtensionSlotConfigs(configState, tempConfigState) {\n const allConfigs = mergeConfigs(getProvidedConfigs(configState, tempConfigState));\n const slotConfigPerModule = Object.keys(allConfigs).reduce((obj, key)=>{\n if (allConfigs[key]?.extensionSlots) {\n obj[key] = allConfigs[key]?.extensionSlots;\n }\n return obj;\n }, {});\n validateAllExtensionSlotConfigs(slotConfigPerModule);\n const slotConfigs = Object.keys(slotConfigPerModule).reduce((obj, key)=>{\n obj = {\n ...obj,\n ...slotConfigPerModule[key]\n };\n return obj;\n }, {});\n return slotConfigs;\n}\nfunction validateAllExtensionSlotConfigs(slotConfigPerModule) {\n for (let [moduleName, configBySlotName] of Object.entries(slotConfigPerModule)){\n for (let [slotName, config] of Object.entries(configBySlotName)){\n validateExtensionSlotConfig(config, moduleName, slotName);\n }\n }\n}\nfunction validateExtensionSlotConfig(config, moduleName, slotName) {\n const keyPath = `${moduleName}.extensionSlots.${slotName}`;\n const errorPrefix = `Extension slot config '${keyPath}'`;\n const invalidKeys = Object.keys(config).filter((k)=>![\n 'add',\n 'remove',\n 'order',\n 'configure'\n ].includes(k));\n if (invalidKeys.length) {\n logError(keyPath, errorPrefix + `' contains invalid keys '${invalidKeys.join(\"', '\")}'`);\n }\n if (config.add) {\n if (!Array.isArray(config.add) || !config.add.every((n)=>typeof n === 'string')) {\n logError(keyPath, errorPrefix + `.add' is invalid. Must be an array of strings (extension IDs)`);\n }\n }\n if (config.remove) {\n if (!Array.isArray(config.remove) || !config.remove.every((n)=>typeof n === 'string')) {\n logError(keyPath, errorPrefix + `.remove' is invalid. Must be an array of strings (extension IDs)`);\n }\n }\n if (config.order) {\n if (!Array.isArray(config.order) || !config.order.every((n)=>typeof n === 'string')) {\n logError(keyPath, errorPrefix + `.order' is invalid. Must be an array of strings (extension IDs)`);\n }\n }\n if (config.configure) {\n if (!isOrdinaryObject(config.configure)) {\n logError(keyPath, errorPrefix + `.configure' is invalid. Must be an object with extension IDs for keys`);\n }\n }\n}\nfunction getProvidedConfigs(configState, tempConfigState) {\n return [\n ...configState.providedConfigs.map((c)=>c.config),\n tempConfigState.config\n ];\n}\n/**\n * Validates the config schema for a module. Since problems identified here are programming errors\n * that hopefully will be caught during development, this function logs errors to the console directly;\n * it's fine if we spam the user with these errors.\n */ function validateConfigSchema(moduleName, schema, keyPath = '') {\n const updateMessage = `Please verify that you are running the latest version and, if so, alert the maintainer.`;\n for (const key of Object.keys(schema).filter((k)=>!k.startsWith('_'))){\n const thisKeyPath = keyPath + (keyPath && '.') + key;\n const schemaPart = schema[key];\n if (thisKeyPath === 'Display conditions') {\n console.error(`${moduleName} declares a configuration option called \"Display conditions\"; the \"Display conditions\" option is a reserved name. ${updateMessage}`);\n }\n if (thisKeyPath === 'Translation overrides') {\n console.error(`${moduleName} declares a configuration option called \"Translation overrides\"; the \"Translation overrides\" option is a reserved name. ${updateMessage}`);\n }\n if (!isOrdinaryObject(schemaPart)) {\n console.error(`${moduleName} has bad config schema definition for key '${thisKeyPath}'. ${updateMessage}`);\n continue;\n }\n if (!schemaPart.hasOwnProperty('_default')) {\n // recurse for nested config keys\n validateConfigSchema(moduleName, schemaPart, thisKeyPath);\n }\n const elements = schemaPart._elements;\n if (hasObjectSchema(elements)) {\n validateConfigSchema(moduleName, elements, thisKeyPath + '._elements');\n }\n if (schemaPart._validators) {\n for (let validator of schemaPart._validators){\n if (typeof validator !== 'function') {\n console.error(`${moduleName} has invalid validator for key '${thisKeyPath}' ${updateMessage}.` + `\\n\\nIf you're the maintainer: validators must be functions that return either ` + `undefined or an error string. Received ${validator}.`);\n }\n }\n }\n const valueType = schemaPart._type;\n if (valueType && !Object.values(_types_js__WEBPACK_IMPORTED_MODULE_0__.Type).includes(valueType)) {\n console.error(`${moduleName} has invalid type for key '${thisKeyPath}' ${updateMessage}.` + `\\n\\nIf you're the maintainer: the allowed types are ${Object.values(_types_js__WEBPACK_IMPORTED_MODULE_0__.Type).join(', ')}. ` + `Received '${valueType}'`);\n }\n if (Object.keys(schemaPart).every((k)=>[\n '_description',\n '_validators',\n '_elements',\n '_type'\n ].includes(k)) && !keyPath.includes('._elements')) {\n console.error(`${moduleName} has bad config schema definition for key '${thisKeyPath}'. ${updateMessage}.` + `\\n\\nIf you're the maintainer: all config elements must have a default. ` + `Received ${JSON.stringify(schemaPart)}`);\n }\n if (elements && valueType && ![\n _types_js__WEBPACK_IMPORTED_MODULE_0__.Type.Array,\n _types_js__WEBPACK_IMPORTED_MODULE_0__.Type.Object\n ].includes(valueType)) {\n console.error(`${moduleName} has bad config schema definition for key '${thisKeyPath}'. ${updateMessage}.` + `\\n\\nIf you're the maintainer: the 'elements' key only works with '_type' equal to 'Array' or 'Object'. ` + `Received ${JSON.stringify(valueType)}`);\n }\n }\n}\nfunction getConfigForModule(moduleName, configState, tempConfigState) {\n const schema = configState.schemas[moduleName];\n const inputConfig = mergeConfigsFor(moduleName, getProvidedConfigs(configState, tempConfigState));\n validateStructure(schema, inputConfig, moduleName);\n const config = setDefaults(schema, inputConfig);\n runAllValidatorsInConfigTree(schema, config, moduleName);\n delete config.extensionSlots;\n return config;\n}\nfunction getConfigForModuleImplicitSchema(moduleName, configState, tempConfigState) {\n const inputConfig = mergeConfigsFor(moduleName, getProvidedConfigs(configState, tempConfigState));\n const config = setDefaults(implicitConfigSchema, inputConfig);\n runAllValidatorsInConfigTree(implicitConfigSchema, config, moduleName);\n delete config.extensionSlots;\n return config;\n}\nfunction mergeConfigsFor(moduleName, allConfigs) {\n const allConfigsForModule = allConfigs.map(({ [moduleName]: c })=>c).filter((c)=>!!c);\n return mergeConfigs(allConfigsForModule);\n}\nfunction mergeConfigs(configs) {\n const mergeDeepAll = (0,ramda__WEBPACK_IMPORTED_MODULE_8__[\"default\"])(ramda__WEBPACK_IMPORTED_MODULE_5__[\"default\"]);\n return mergeDeepAll({}, configs);\n}\n/**\n * Recursively check the provided config tree to make sure that all\n * of the provided properties exist in the schema, and that types are\n * correct. Does not run validators yet, since those will be run on\n * the config with the defaults filled in.\n */ function validateStructure(schema, config, keyPath = '') {\n // validate each constituent element\n for (const key of Object.keys(config)){\n const value = config[key];\n const thisKeyPath = keyPath + '.' + key;\n const schemaPart = schema[key];\n if (!schema.hasOwnProperty(key)) {\n if (!(key === 'extensionSlots' && keyPath !== '')) {\n logError(thisKeyPath, `Unknown config key '${thisKeyPath}' provided. Ignoring.`);\n }\n continue;\n }\n validateBranchStructure(schemaPart, value, thisKeyPath);\n }\n}\nfunction validateBranchStructure(schemaPart, value, keyPath) {\n checkType(keyPath, schemaPart._type, value);\n if (isOrdinaryObject(value)) {\n if (schemaPart._type === _types_js__WEBPACK_IMPORTED_MODULE_0__.Type.Object) {\n // validate as freeform object\n validateFreeformObjectStructure(schemaPart, value, keyPath);\n } else if (!(schemaPart.hasOwnProperty('_default') || schemaPart.hasOwnProperty('_type'))) {\n // validate as normal nested config\n validateStructure(schemaPart, value, keyPath);\n }\n } else {\n if (schemaPart._type === _types_js__WEBPACK_IMPORTED_MODULE_0__.Type.Array) {\n validateArrayStructure(schemaPart, value, keyPath);\n }\n }\n}\nfunction validateFreeformObjectStructure(freeformObjectSchema, config, keyPath) {\n if (freeformObjectSchema._elements) {\n for (const key of Object.keys(config)){\n const value = config[key];\n validateBranchStructure(freeformObjectSchema._elements, value, `${keyPath}.${key}`);\n }\n }\n}\nfunction validateArrayStructure(arraySchema, value, keyPath) {\n const validatedAsArray = checkType(keyPath, _types_js__WEBPACK_IMPORTED_MODULE_0__.Type.Array, value);\n if (!validatedAsArray) {\n return;\n }\n // if there is an array element object schema, verify that elements match it\n if (hasObjectSchema(arraySchema._elements)) {\n for(let i = 0; i < value.length; i++){\n validateBranchStructure(arraySchema._elements, value[i], `${keyPath}[${i}]`);\n }\n }\n for(let i = 0; i < value.length; i++){\n checkType(`${keyPath}[${i}]`, arraySchema._elements?._type, value[i]);\n }\n}\n/**\n * Run all the validators in the config tree. This should be run\n * on the config object after it has been filled in with all the defaults, since\n * higher-level validators may refer to default values.\n */ function runAllValidatorsInConfigTree(schema, config, keyPath = '') {\n // If `!schema`, there should have been a structural validation error printed already.\n if (schema) {\n if (config !== schema._default) {\n runValidators(keyPath, schema._validators, config);\n }\n if (isOrdinaryObject(config)) {\n for (const key of Object.keys(config)){\n const value = config[key];\n const thisKeyPath = keyPath + '.' + key;\n const schemaPart = schema[key];\n if (schema._type === _types_js__WEBPACK_IMPORTED_MODULE_0__.Type.Object && schema._elements) {\n runAllValidatorsInConfigTree(schema._elements, value, thisKeyPath);\n } else {\n runAllValidatorsInConfigTree(schemaPart, value, thisKeyPath);\n }\n }\n } else if (Array.isArray(config) && schema._elements) {\n for(let i = 0; i < config.length; i++){\n runAllValidatorsInConfigTree(schema._elements, config[i], `${keyPath}[${i}]`);\n }\n }\n }\n}\n/**\n * Run type validation for the value, logging any errors.\n * @returns true if validation passes, false otherwise\n */ function checkType(keyPath, _type, value) {\n if (_type) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\n const validator = {\n Array: _validators_type_validators_js__WEBPACK_IMPORTED_MODULE_1__.isArray,\n Boolean: _validators_type_validators_js__WEBPACK_IMPORTED_MODULE_1__.isBoolean,\n ConceptUuid: _validators_type_validators_js__WEBPACK_IMPORTED_MODULE_1__.isUuid,\n Number: _validators_type_validators_js__WEBPACK_IMPORTED_MODULE_1__.isNumber,\n Object: _validators_type_validators_js__WEBPACK_IMPORTED_MODULE_1__.isObject,\n String: _validators_type_validators_js__WEBPACK_IMPORTED_MODULE_1__.isString,\n UUID: _validators_type_validators_js__WEBPACK_IMPORTED_MODULE_1__.isUuid,\n PersonAttributeTypeUuid: _validators_type_validators_js__WEBPACK_IMPORTED_MODULE_1__.isUuid,\n PatientIdentifierTypeUuid: _validators_type_validators_js__WEBPACK_IMPORTED_MODULE_1__.isUuid\n };\n return runValidators(keyPath, [\n validator[_type]\n ], value);\n }\n return true;\n}\n/**\n * Runs validators, logging errors.\n * @returns true if all pass, false otherwise.\n */ // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\nfunction runValidators(keyPath, validators, value) {\n let returnValue = true;\n if (validators) {\n try {\n for (let validator of validators){\n const validatorResult = validator(value);\n if (typeof validatorResult === 'string') {\n const message = typeof value === 'object' ? `Invalid configuration for ${keyPath}: ${validatorResult}` : `Invalid configuration value ${value} for ${keyPath}: ${validatorResult}`;\n logError(keyPath, message);\n returnValue = false;\n }\n }\n } catch (e) {\n console.error(`Skipping invalid validator at \"${keyPath}\". Encountered error\\n\\t${e}`);\n }\n }\n return returnValue;\n}\n// Recursively fill in the config with values from the schema.\nconst setDefaults = (schema, inputConfig)=>{\n const config = (0,ramda__WEBPACK_IMPORTED_MODULE_7__[\"default\"])(inputConfig);\n if (!schema) {\n return config;\n }\n for (const key of Object.keys(schema)){\n const configPart = config[key];\n const schemaPart = schema[key];\n // The `schemaPart &&` clause of this `if` statement will only fail\n // if the schema is very invalid. It is there to prevent the app from\n // crashing completely, though it will produce unexpected behavior.\n // If this happens, there should be legible errors in the console from\n // the schema validator.\n if (schemaPart && (schemaPart.hasOwnProperty('_type') || schemaPart.hasOwnProperty('_default'))) {\n // We assume that schemaPart defines a config value, since it has\n // a property `_type` or `_default`.\n if (!config.hasOwnProperty(key)) {\n config[key] = schemaPart['_default'];\n }\n // We also check if it is an object or array with object elements, in which case we recurse\n const elements = schemaPart._elements;\n if (configPart && hasObjectSchema(elements)) {\n if (schemaPart._type === _types_js__WEBPACK_IMPORTED_MODULE_0__.Type.Array && Array.isArray(configPart)) {\n const configWithDefaults = configPart.map((conf)=>setDefaults(elements, conf));\n config[key] = configWithDefaults;\n } else if (schemaPart._type === _types_js__WEBPACK_IMPORTED_MODULE_0__.Type.Object) {\n for (let objectKey of Object.keys(configPart)){\n configPart[objectKey] = setDefaults(elements, configPart[objectKey]);\n }\n }\n }\n } else if (isOrdinaryObject(schemaPart)) {\n // Since schemaPart has no property \"_type\", if it's an ordinary object\n // (unlike, importantly, the validators array), we assume it is a parent config property.\n // We recurse to config[key] and schema[key]. Default config[key] to {}.\n const selectedConfigPart = configPart ?? {};\n // There will have been a validation error already if configPart is not a plain object.\n if (isOrdinaryObject(selectedConfigPart)) {\n config[key] = setDefaults(schemaPart, selectedConfigPart);\n }\n }\n }\n return config;\n};\nfunction hasObjectSchema(elementsSchema) {\n return !!elementsSchema && Object.keys(elementsSchema).filter((e)=>![\n '_default',\n '_validators'\n ].includes(e)).length > 0;\n}\nfunction isOrdinaryObject(value) {\n return typeof value === 'object' && !Array.isArray(value) && value !== null;\n}\n/** Keep track of which validation errors we have displayed. Each one should only be displayed once. */ let displayedValidationMessages = new Set();\nfunction logError(keyPath, message) {\n const key = `${keyPath}:::${message}`;\n // technically, this should not be possible, but because of how things wind-up transpiled, this isn't impossible\n if (!displayedValidationMessages) {\n displayedValidationMessages = new Set();\n }\n if (!displayedValidationMessages.has(key)) {\n console.error(message);\n displayedValidationMessages.add(key);\n }\n}\n/**\n * Normally, configuration errors are only displayed once. This function clears the list of\n * displayed errors, so that they will be displayed again.\n *\n * @internal\n */ function clearConfigErrors(keyPath) {\n if (keyPath) {\n displayedValidationMessages.forEach((key)=>{\n if (key.startsWith(keyPath)) {\n displayedValidationMessages.delete(key);\n }\n });\n } else {\n displayedValidationMessages.clear();\n }\n}\n/**\n * Cleans up all config store subscriptions and re-establishes them. This is primarily\n * useful for testing, where subscriptions set up at module load time need to be cleared\n * between tests to prevent infinite update loops. After clearing, subscriptions are\n * re-established so the config system continues to work normally.\n *\n * @internal\n */ function resetConfigSystem() {\n configSubscriptions.forEach((unsubscribe)=>unsubscribe());\n configSubscriptions.length = 0;\n setupConfigSubscriptions();\n}\n/**\n * Copied over from esm-extensions. It rightly belongs to that module, but esm-config\n * cannot depend on esm-extensions.\n */ function getExtensionNameFromId(extensionId) {\n const [extensionName] = extensionId.split('#');\n return extensionName;\n}\n/**\n * The translation overrides schema is used in the implicit schema given to every module;\n * plus any additional translation namespaces (at time of writing, this is just 'core').\n */ const translationOverridesSchema = {\n 'Translation overrides': {\n _description: 'Per-language overrides for frontend translations should be keyed by language code and each language dictionary contains the translation key and the display value',\n _type: _types_js__WEBPACK_IMPORTED_MODULE_0__.Type.Object,\n _default: {},\n _validators: [\n (0,_validators_validator_js__WEBPACK_IMPORTED_MODULE_2__.validator)((o)=>Object.keys(o).every((k)=>/^[a-z]{2,3}(-[A-Z]{2,3})?$/.test(k)), (o)=>{\n const badKeys = Object.keys(o).filter((k)=>!/^[a-z]{2,3}(-[A-Z]{2,3})?$/.test(k));\n return `The 'Translation overrides' object should have language codes for keys. Language codes must be in the form of a two-to-three letter language code optionally followed by a hyphen and a two-to-three letter country code. The following keys do not conform: ${badKeys.join(', ')}.`;\n })\n ]\n }\n};\n/**\n * The implicitConfigSchema is implicitly included in every configuration schema\n */ const implicitConfigSchema = {\n 'Display conditions': {\n privileges: {\n _description: 'The privilege(s) the user must have to use this extension',\n _type: _types_js__WEBPACK_IMPORTED_MODULE_0__.Type.Array,\n _default: []\n },\n expression: {\n _description: 'The expression that determines whether the extension is displayed',\n _type: _types_js__WEBPACK_IMPORTED_MODULE_0__.Type.String,\n _default: undefined\n }\n },\n ...translationOverridesSchema\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi4vLi4vZnJhbWV3b3JrL2VzbS1jb25maWcvZGlzdC9tb2R1bGUtY29uZmlnL21vZHVsZS1jb25maWcuanMiLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSw2QkFBNkIsR0FBdUU7QUFDakU7QUFDeUU7QUFDckQ7QUFDK0o7QUFDdE47Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Q0FtQkMsR0FBRyx3RkFBd0Y7QUFDNUYsTUFBTXFCLHNCQUFzQixFQUFFO0FBQzlCOzs7Q0FHQyxHQUFHLFNBQVNDO0lBQ1QsTUFBTUMsY0FBY1QsMERBQW1CQSxDQUFDVSxRQUFRO0lBQ2hELE1BQU1DLGtCQUFrQkwsMkRBQW9CQSxDQUFDSSxRQUFRO0lBQ3JELE1BQU1FLGlCQUFpQmIsMkRBQW9CQSxDQUFDVyxRQUFRO0lBQ3BERyxvQkFBb0JKLGFBQWFFO0lBQ2pDRyw4QkFBOEJMLGFBQWFFO0lBQzNDSSw0QkFBNEJOLGFBQWFFO0lBQ3pDSyx3QkFBd0JQLGFBQWFHLGdCQUFnQkQ7QUFDekQ7QUFDQSxTQUFTTTtJQUNMLHNCQUFzQjtJQUN0QlQ7SUFDQSxzREFBc0Q7SUFDdEQsb0ZBQW9GO0lBQ3BGRCxvQkFBb0JXLElBQUksQ0FBQ2xCLDBEQUFtQkEsQ0FBQ21CLFNBQVMsQ0FBQ1g7SUFDdkRELG9CQUFvQlcsSUFBSSxDQUFDWiwyREFBb0JBLENBQUNhLFNBQVMsQ0FBQ1g7SUFDeERELG9CQUFvQlcsSUFBSSxDQUFDbkIsMkRBQW9CQSxDQUFDb0IsU0FBUyxDQUFDWDtBQUM1RDtBQUNBLDJDQUEyQztBQUMzQ1M7QUFDQSxTQUFTSixvQkFBb0JPLEtBQUssRUFBRUMsU0FBUztJQUN6QyxLQUFLLElBQUlDLGNBQWNDLE9BQU9DLElBQUksQ0FBQ0osTUFBTUssT0FBTyxFQUFFO1FBQzlDLG9GQUFvRjtRQUNwRixtRkFBbUY7UUFDbkYsb0ZBQW9GO1FBQ3BGLGlGQUFpRjtRQUNqRixrRkFBa0Y7UUFDbEYsZ0RBQWdEO1FBQ2hELE1BQU1DLGNBQWN6Qix5REFBY0EsQ0FB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QUFTQSxDQUFDLENBQUM2TCxJQUFJcEssT0FBT0MsSUFBSSxDQUFDbUssR0FBRzFELEtBQUssQ0FBQyxDQUFDUCxJQUFJLDZCQUE2QmtFLElBQUksQ0FBQ2xFLEtBQUssQ0FBQ2lFO2dCQUM3RSxNQUFNRSxVQUFVdEssT0FBT0MsSUFBSSxDQUFDbUssR0FBR2xFLE1BQU0sQ0FBQyxDQUFDQyxJQUFJLENBQUMsNkJBQTZCa0UsSUFBSSxDQUFDbEU7Z0JBQzlFLE9BQU8sQ0FBQyw2UEFBNlAsRUFBRW1FLFFBQVEvRCxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDaFM7U0FDSDtJQUNMO0FBQ0o7QUFDQTs7Q0FFQyxHQUFHLE1BQU1wRSx1QkFBdUI7SUFDN0Isc0JBQXNCO1FBQ2xCb0ksWUFBWTtZQUNSSixjQUFjO1lBQ2Q1QyxPQUFPdkosMkNBQUlBLENBQUN5SSxLQUFLO1lBQ2pCcEIsVUFBVSxFQUFFO1FBQ2hCO1FBQ0FtRixZQUFZO1lBQ1JMLGNBQWM7WUFDZDVDLE9BQU92SiwyQ0FBSUEsQ0FBQzJLLE1BQU07WUFDbEJ0RCxVQUFVb0Y7UUFDZDtJQUNKO0lBQ0EsR0FBR2pJLDBCQUEwQjtBQUNqQyIsInNvdXJjZXMiOlsid2VicGFjazovL0BvcGVubXJzL2VzbS1hcHAtc2hlbGwvLi4vLi4vZnJhbWV3b3JrL2VzbS1jb25maWcvZGlzdC9tb2R1bGUtY29uZmlnL21vZHVsZS1jb25maWcuanM/OGRmZSJdLCJzb3VyY2VzQ29udGVudCI6WyIvKiogQG1vZHVsZSBAY2F0ZWdvcnkgQ29uZmlnICovIGltcG9ydCB7IGNsb25lLCBlcXVhbHMsIHJlZHVjZSwgbWVyZ2VEZWVwUmlnaHQsIG9taXQgfSBmcm9tIFwicmFtZGFcIjtcbmltcG9ydCB7IFR5cGUgfSBmcm9tIFwiLi4vdHlwZXMuanNcIjtcbmltcG9ydCB7IGlzQXJyYXksIGlzQm9vbGVhbiwgaXNVdWlkLCBpc051bWJlciwgaXNPYmplY3QsIGlzU3RyaW5nIH0gZnJvbSBcIi4uL3ZhbGlkYXRvcnMvdHlwZS12YWxpZGF0b3JzLmpzXCI7XG5pbXBvcnQgeyB2YWxpZGF0b3IgfSBmcm9tIFwiLi4vdmFsaWRhdG9ycy92YWxpZGF0b3IuanNcIjtcbmltcG9ydCB7IGNvbmZpZ0V4dGVuc2lvblN0b3JlLCBjb25maWdJbnRlcm5hbFN0b3JlLCBnZXRDb25maWdTdG9yZSwgZ2V0RXh0ZW5zaW9uQ29uZmlnLCBnZXRFeHRlbnNpb25TbG90c0NvbmZpZ1N0b3JlLCBnZXRFeHRlbnNpb25zQ29uZmlnU3RvcmUsIGltcGxlbWVudGVyVG9vbHNDb25maWdTdG9yZSwgdGVtcG9yYXJ5Q29uZmlnU3RvcmUgfSBmcm9tIFwiLi9zdGF0ZS5qc1wiO1xuLyoqXG4gKiBTdG9yZSBzZXR1cFxuICpcbiAqXG4gKiBTZXQgdXAgc3RvcmVzIGFuZCBzdWJzY3JpcHRpb25zIHNvIHRoYXQgaW5wdXRzIGdldCBwcm9jZXNzZWQgYXBwcm9wcmlhdGVseS5cbiAqXG4gKiBUaGVyZSBhcmUgKmlucHV0KiBzdG9yZXMgYW5kICpvdXRwdXQqIHN0b3Jlcy4gVGhlICppbnB1dCogc3RvcmVzXG4gKiBhcmUgY29uZmlnSW50ZXJuYWxTdG9yZSwgdGVtcG9yYXJ5Q29uZmlnU3RvcmUsIGFuZCBjb25maWdFeHRlbnNpb25TdG9yZS4gVGhlXG4gKiBvdXRwdXQgc3RvcmVzIGFyZSBzZXQgaW4gdGhlIGBjb21wdXRlLi4uYCBmdW5jdGlvbnMuIFRoZXkgYXJlIHRoZSBtb2R1bGVcbiAqIGNvbmZpZyBzdG9yZXMsIHRoZSBleHRlbnNpb24gc2xvdCBjb25maWcgc3RvcmVzIChieSBtb2R1bGUpLCB0aGUgZXh0ZW5zaW9uXG4gKiBjb25maWcgc3RvcmVzLCBhbmQgdGhlIGltcGxlbWVudGVyIHRvb2xzIGNvbmZpZyBzdG9yZS5cbiAqXG4gKiBUaGlzIGNvZGUgc2V0cyB1cCB0aGUgc3Vic2NyaXB0aW9ucyBzbyB0aGF0IHdoZW4gYW4gaW5wdXQgc3RvcmUgY2hhbmdlcyxcbiAqIHRoZSBjb3JyZWN0IHNldCBvZiBvdXRwdXQgc3RvcmVzIGFyZSB1cGRhdGVkLlxuICpcbiAqIEFsbCBgY29tcHV0ZS4uLmAgZnVuY3Rpb25zIGV4Y2VwdCBgY29tcHV0ZUV4dGVuc2lvbkNvbmZpZ3NgIGFyZSBwdXJlXG4gKiAob3IgYXJlIHN1cHBvc2VkIHRvIGJlKSwgb3RoZXIgdGhhbiB0aGUgZmFjdCB0aGF0IHRoZXkgYWxsIGBzZXRTdGF0ZWBcbiAqIHN0b3JlIHZhbHVlcyBhdCB0aGUgZW5kLiBgY29tcHV0ZUV4dGVuc2lvbkNvbmZpZ3NgIGNhbGxzIGBnZXRHbG9iYWxTdG9yZWAsXG4gKiB3aGljaCBjcmVhdGVzIHN0b3Jlcy5cbiAqLyAvLyBTdG9yZSB1bnN1YnNjcmliZSBmdW5jdGlvbnMgdG8gYWxsb3cgY2xlYW51cCAoZS5nLiwgaW4gdGVzdHMgb3IgaG90IG1vZHVsZSByZWxvYWRpbmcpXG5jb25zdCBjb25maWdTdWJzY3JpcHRpb25zID0gW107XG4vKipcbiAqIFJlY29tcHV0ZXMgYWxsIGNvbmZpZ3VyYXRpb24gZGVyaXZlZCBzdG9yZXMgYmFzZWQgb24gY3VycmVudCBzdGF0ZSBvZiBpbnB1dCBzdG9yZXMuXG4gKiBDYWxsZWQgd2hlbmV2ZXIgYW55IGlucHV0IHN0b3JlIChjb25maWdJbnRlcm5hbFN0b3JlLCB0ZW1wb3JhcnlDb25maWdTdG9yZSwgY29uZmlnRXh0ZW5zaW9uU3RvcmUpIGNoYW5nZXMuXG4gKi8gZnVuY3Rpb24gcmVjb21wdXRlQWxsQ29uZmlncygpIHtcbiAgICBjb25zdCBjb25maWdTdGF0ZSA9IGNvbmZpZ0ludGVybmFsU3RvcmUuZ2V0U3RhdGUoKTtcbiAgICBjb25zdCB0ZW1wQ29uZmlnU3RhdGUgPSB0ZW1wb3JhcnlDb25maWdTdG9yZS5nZXRTdGF0ZSgpO1xuICAgIGNvbnN0IGV4dGVuc2lvblN0YXRlID0gY29uZmlnRXh0ZW5zaW9uU3RvcmUuZ2V0U3RhdGUoKTtcbiAgICBjb21wdXRlTW9kdWxlQ29uZmlnKGNvbmZpZ1N0YXRlLCB0ZW1wQ29uZmlnU3RhdGUpO1xuICAgIGNvbXB1dGVJbXBsZW1lbnRlclRvb2xzQ29uZmlnKGNvbmZpZ1N0YXRlLCB0ZW1wQ29uZmlnU3RhdGUpO1xuICAgIGNvbXB1dGVFeHRlbnNpb25TbG90Q29uZmlncyhjb25maWdTdGF0ZSwgdGVtcENvbmZpZ1N0YXRlKTtcbiAgICBjb21wdXRlRXh0ZW5zaW9uQ29uZmlncyhjb25maWdTdGF0ZSwgZXh0ZW5zaW9uU3RhdGUsIHRlbXBDb25maWdTdGF0ZSk7XG59XG5mdW5jdGlvbiBzZXR1cENvbmZpZ1N1YnNjcmlwdGlvbnMoKSB7XG4gICAgLy8gSW5pdGlhbCBjb21wdXRhdGlvblxuICAgIHJlY29tcHV0ZUFsbENvbmZpZ3MoKTtcbiAgICAvLyBTdWJzY3JpYmUgdG8gYWxsIGlucHV0IHN0b3JlcyB3aXRoIGEgc2luZ2xlIGhhbmRsZXJcbiAgICAvLyBUaGlzIGVuc3VyZXMgd2Ugb25seSByZWNvbXB1dGUgb25jZSBldmVuIGlmIG11bHRpcGxlIHN0b3JlcyBjaGFuZ2Ugc2ltdWx0YW5lb3VzbHlcbiAgICBjb25maWdTdWJzY3JpcHRpb25zLnB1c2goY29uZmlnSW50ZXJuYWxTdG9yZS5zdWJzY3JpYmUocmVjb21wdXRlQWxsQ29uZmlncykpO1xuICAgIGNvbmZpZ1N1YnNjcmlwdGlvbnMucHVzaCh0ZW1wb3JhcnlDb25maWdTdG9yZS5zdWJzY3JpYmUocmVjb21wdXRlQWxsQ29uZmlncykpO1xuICAgIGNvbmZpZ1N1YnNjcmlwdGlvbnMucHVzaChjb25maWdFeHRlbnNpb25TdG9yZS5zdWJzY3JpYmUocmVjb21wdXRlQWxsQ29uZmlncykpO1xufVxuLy8gU2V0IHVwIHN1YnNjcmlwdGlvbnMgYXQgbW9kdWxlIGxvYWQgdGltZVxuc2V0dXBDb25maWdTdWJzY3JpcHRpb25zKCk7XG5mdW5jdGlvbiBjb21wdXRlTW9kdWxlQ29uZmlnKHN0YXRlLCB0ZW1wU3RhdGUpIHtcbiAgICBmb3IgKGxldCBtb2R1bGVOYW1lIG9mIE9iamVjdC5rZXlzKHN0YXRlLnNjaGVtYXMpKXtcbiAgICAgICAgLy8gQXQgdGhpcyBwb2ludCB0aGUgc2NoZW1hIGNvdWxkIGJlIGVpdGhlciBqdXN0IHRoZSBpbXBsaWNpdCBzY2hlbWEgb3IgdGhlIGFjdHVhbGx5XG4gICAgICAgIC8vIGRlZmluZWQgc2NoZW1hLiBXZSBydW4gd2l0aCBqdXN0IHRoZSBpbXBsaWNpdCBzY2hlbWEgYmVjYXVzZSB3ZSB3YW50IHRvIHBvcHVsYXRlXG4gICAgICAgIC8vIHRoZSBjb25maWcgc3RvcmUgd2l0aCB0aGUgdHJhbnNsYXRpb24gb3ZlcnJpZGVzIGFzIHNvb24gYXMgcG9zc2libGUuIEluIGZhY3QsIHRoZVxuICAgICAgICAvLyB0cmFuc2xhdGlvbiBzeXN0ZW0gd2lsbCB0aHJvdyBmb3IgU3VzcGVuc2UgdW50aWwgdGhlIHRyYW5zbGF0aW9uIG92ZXJyaWRlcyBhcmVcbiAgICAgICAgLy8gYXZhaWxhYmxlLCB3aGljaCBhcyBvZiB0aGlzIHdyaXRpbmcgYmxvY2tzIHRoZSBzY2hlbWEgZGVmaW5pdGlvbiBmcm9tIG9jY3VycmluZ1xuICAgICAgICAvLyBmb3IgbW9kdWxlcyBsb2FkZWQgYmFzZWQgb24gdGhlaXIgZXh0ZW5zaW9ucy5cbiAgICAgICAgY29uc3QgbW9kdWxlU3RvcmUgPSBnZXRDb25maWdTdG9yZShtb2R1bGVOYW1lKTtcbiAgICAgICAgbGV0IG5ld1N0YXRlO1xuICAgICAgICBpZiAoc3RhdGUubW9kdWxlTG9hZGVkW21vZHVsZU5hbWVdKSB7XG4gICAgICAgICAgICBjb25zdCBjb25maWcgPSBnZXRDb25maWdGb3JNb2R1bGUobW9kdWxlTmFtZSwgc3RhdGUsIHRlbXBTdGF0ZSk7XG4gICAgICAgICAgICBuZXdTdGF0ZSA9IHtcbiAgICAgICAgICAgICAgICB0cmFuc2xhdGlvbk92ZXJyaWRlc0xvYWRlZDogdHJ1ZSxcbiAgICAgICAgICAgICAgICBsb2FkZWQ6IHRydWUsXG4gICAgICAgICAgICAgICAgY29uZmlnXG4gICAgICAgICAgICB9O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc3QgY29uZmlnID0gZ2V0Q29uZmlnRm9yTW9kdWxlSW1wbGljaXRTY2hlbWEobW9kdWxlTmFtZSwgc3RhdGUsIHRlbXBTdGF0ZSk7XG4gICAgICAgICAgICBuZXdTdGF0ZSA9IHtcbiAgICAgICAgICAgICAgICB0cmFuc2xhdGlvbk92ZXJyaWRlc0xvYWRlZDogdHJ1ZSxcbiAgICAgICAgICAgICAgICBsb2FkZWQ6IGZhbHNlLFxuICAgICAgICAgICAgICAgIGNvbmZpZ1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICBtb2R1bGVTdG9yZS5zZXRTdGF0ZShuZXdTdGF0ZSk7XG4gICAgfVxufVxuZnVuY3Rpb24gY29tcHV0ZUV4dGVuc2lvblNsb3RDb25maWdzKHN0YXRlLCB0ZW1wU3RhdGUpIHtcbiAgICBjb25zdCBzbG90Q29uZmlncyA9IGdldEV4dGVuc2lvblNsb3RDb25maWdzKHN0YXRlLCB0ZW1wU3RhdGUpO1xuICAgIGNvbnN0IG5ld1Nsb3RTdG9yZUVudHJpZXMgPSBPYmplY3QuZnJvbUVudHJpZXMoT2JqZWN0LmVudHJpZXMoc2xvdENvbmZpZ3MpLm1hcCgoW3Nsb3ROYW1lLCBjb25maWddKT0+W1xuICAgICAgICAgICAgc2xvdE5hbWUsXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgbG9hZGVkOiB0cnVlLFxuICAgICAgICAgICAgICAgIGNvbmZpZ1xuICAgICAgICAgICAgfVxuICAgICAgICBdKSk7XG4gICAgY29uc3Qgc2xvdFN0b3JlID0gZ2V0RXh0ZW5zaW9uU2xvdHNDb25maWdTdG9yZSgpO1xuICAgIGNvbnN0IG9sZFN0YXRlID0gc2xvdFN0b3JlLmdldFN0YXRlKCk7XG4gICAgY29uc3QgbmV3U3RhdGUgPSB7XG4gICAgICAgIHNsb3RzOiB7XG4gICAgICAgICAgICAuLi5vbGRTdGF0ZS5zbG90cyxcbiAgICAgICAgICAgIC4uLm5ld1Nsb3RTdG9yZUVudHJpZXNcbiAgICAgICAgfVxuICAgIH07XG4gICAgaWYgKCFlcXVhbHMob2xkU3RhdGUuc2xvdHMsIG5ld1N0YXRlLnNsb3RzKSkge1xuICAgICAgICBzbG90U3RvcmUuc2V0U3RhdGUobmV3U3RhdGUpO1xuICAgIH1cbn1cbmZ1bmN0aW9uIGNvbXB1dGVJbXBsZW1lbnRlclRvb2xzQ29uZmlnKHN0YXRlLCB0ZW1wQ29uZmlnU3RhdGUpIHtcbiAgICBjb25zdCBvbGRTdGF0ZSA9IGltcGxlbWVudGVyVG9vbHNDb25maWdTdG9yZS5nZXRTdGF0ZSgpO1xuICAgIGNvbnN0IGNvbmZpZyA9IGdldEltcGxlbWVudGVyVG9vbHNDb25maWcoc3RhdGUsIHRlbXBDb25maWdTdGF0ZSk7XG4gICAgY29uc3QgbmV3U3RhdGUgPSB7XG4gICAgICAgIGNvbmZpZ1xuICAgIH07XG4gICAgLy8gVXNlIGRlZXAgZXF1YWxpdHkgb24gdGhlIGFjdHVhbCBjb25maWcgY29udGVudCwgbm90IHRoZSB3cmFwcGVyIG9iamVjdFxuICAgIGlmICghZXF1YWxzKG9sZFN0YXRlLmNvbmZpZywgbmV3U3RhdGUuY29uZmlnKSkge1xuICAgICAgICBpbXBsZW1lbnRlclRvb2xzQ29uZmlnU3RvcmUuc2V0U3RhdGUobmV3U3RhdGUpO1xuICAgIH1cbn1cbmZ1bmN0aW9uIGNvbXB1dGVFeHRlbnNpb25Db25maWdzKGNvbmZpZ1N0YXRlLCBleHRlbnNpb25TdGF0ZSwgdGVtcENvbmZpZ1N0YXRlKSB7XG4gICAgY29uc3QgY29uZmlncyA9IHt9O1xuICAgIC8vIFdlIGFzc3VtZSB0aGF0IHRoZSBtb2R1bGUgc2NoZW1hIGhhcyBhbHJlYWR5IGJlZW4gZGVmaW5lZCwgc2luY2UgdGhlIGV4dGVuc2lvblxuICAgIC8vIGl0IGNvbnRhaW5zIGlzIG1vdW50ZWQuXG4gICAgZm9yIChsZXQgZXh0ZW5zaW9uIG9mIGV4dGVuc2lvblN0YXRlLm1vdW50ZWRFeHRlbnNpb25zKXtcbiAgICAgICAgY29uc3QgY29uZmlnID0gY29tcHV0ZUV4dGVuc2lvbkNvbmZpZyhleHRlbnNpb24uc2xvdE1vZHVsZU5hbWUsIGV4dGVuc2lvbi5leHRlbnNpb25Nb2R1bGVOYW1lLCBleHRlbnNpb24uc2xvdE5hbWUsIGV4dGVuc2lvbi5leHRlbnNpb25JZCwgY29uZmlnU3RhdGUsIHRlbXBDb25maWdTdGF0ZSk7XG4gICAgICAgIGlmICghY29uZmlnc1tleHRlbnNpb24uc2xvdE5hbWVdKSB7XG4gICAgICAgICAgICBjb25maWdzW2V4dGVuc2lvbi5zbG90TmFtZV0gPSB7fTtcbiAgICAgICAgfVxuICAgICAgICBjb25maWdzW2V4dGVuc2lvbi5zbG90TmFtZV1bZXh0ZW5zaW9uLmV4dGVuc2lvbklkXSA9IHtcbiAgICAgICAgICAgIGNvbmZpZyxcbiAgICAgICAgICAgIGxvYWRlZDogdHJ1ZVxuICAgICAgICB9O1xuICAgIH1cbiAgICBjb25zdCBleHRlbnNpb25zQ29uZmlnU3RvcmUgPSBnZXRFeHRlbnNpb25zQ29uZmlnU3RvcmUoKTtcbiAgICBjb25zdCBvbGRTdGF0ZSA9IGV4dGVuc2lvbnNDb25maWdTdG9yZS5nZXRTdGF0ZSgpO1xuICAgIGNvbnN0IG5ld1N0YXRlID0ge1xuICAgICAgICBjb25maWdzXG4gICAgfTtcbiAgICAvLyBVc2UgZGVlcCBlcXVhbGl0eSB0byBvbmx5IHVwZGF0ZSBpZiBjb25maWdzIGFjdHVhbGx5IGNoYW5nZWRcbiAgICBpZiAoIWVxdWFscyhvbGRTdGF0ZS5jb25maWdzLCBuZXdTdGF0ZS5jb25maWdzKSkge1xuICAgICAgICBleHRlbnNpb25zQ29uZmlnU3RvcmUuc2V0U3RhdGUobmV3U3RhdGUpO1xuICAgIH1cbn1cbi8qXG4gKiBBUElcbiAqXG4gKi8gLyoqXG4gKiBUaGlzIGRlZmluZXMgYSBjb25maWd1cmF0aW9uIHNjaGVtYSBmb3IgYSBtb2R1bGUuIFRoZSBzY2hlbWEgdGVsbHMgdGhlXG4gKiBjb25maWd1cmF0aW9uIHN5c3RlbSBob3cgdGhlIG1vZHVsZSBjYW4gYmUgY29uZmlndXJlZC4gSXQgc3BlY2lmaWVzXG4gKiB3aGF0IG1ha2VzIGNvbmZpZ3VyYXRpb24gdmFsaWQgb3IgaW52YWxpZC5cbiAqXG4gKiBTZWUgW0NvbmZpZ3VyYXRpb24gU3lzdGVtXShodHRwczovL28zLWRvY3Mub3Blbm1ycy5vcmcvZG9jcy9jb25maWd1cmF0aW9uLXN5c3RlbSlcbiAqIGZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IGRlZmluaW5nIGEgY29uZmlnIHNjaGVtYS5cbiAqXG4gKiBAcGFyYW0gbW9kdWxlTmFtZSBOYW1lIG9mIHRoZSBtb2R1bGUgdGhlIHNjaGVtYSBpcyBiZWluZyBkZWZpbmVkIGZvci4gR2VuZXJhbGx5XG4gKiAgIHNob3VsZCBiZSB0aGUgb25lIGluIHdoaWNoIHRoZSBgZGVmaW5lQ29uZmlnU2NoZW1hYCBjYWxsIHRha2VzIHBsYWNlLlxuICogQHBhcmFtIHNjaGVtYSBUaGUgY29uZmlnIHNjaGVtYSBmb3IgdGhlIG1vZHVsZVxuICovIGV4cG9ydCBmdW5jdGlvbiBkZWZpbmVDb25maWdTY2hlbWEobW9kdWxlTmFtZSwgc2NoZW1hKSB7XG4gICAgdmFsaWRhdGVDb25maWdTY2hlbWEobW9kdWxlTmFtZSwgc2NoZW1hKTtcbiAgICBjb25zdCBlbmhhbmNlZFNjaGVtYSA9IG1lcmdlRGVlcFJpZ2h0KHNjaGVtYSwgaW1wbGljaXRDb25maWdTY2hlbWEpO1xuICAgIGNvbmZpZ0ludGVybmFsU3RvcmUuc2V0U3RhdGUoKHN0YXRlKT0+KHtcbiAgICAgICAgICAgIC4uLnN0YXRlLFxuICAgICAgICAgICAgc2NoZW1hczoge1xuICAgICAgICAgICAgICAgIC4uLnN0YXRlLnNjaGVtYXMsXG4gICAgICAgICAgICAgICAgW21vZHVsZU5hbWVdOiBlbmhhbmNlZFNjaGVtYVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIG1vZHVsZUxvYWRlZDoge1xuICAgICAgICAgICAgICAgIC4uLnN0YXRlLm1vZHVsZUxvYWRlZCxcbiAgICAgICAgICAgICAgICBbbW9kdWxlTmFtZV06IHRydWVcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSkpO1xufVxuLyoqXG4gKiBUaGlzIGFsZXJ0cyB0aGUgY29uZmlndXJhdGlvbiBzeXN0ZW0gdGhhdCBhIG1vZHVsZSBleGlzdHMuIFRoaXMgYWxsb3dzIGNvbmZpZyB0byBiZVxuICogcHJvY2Vzc2VkLCB3aGlsZSBzdGlsbCBhbGxvd2luZyB0aGUgZXh0ZW5zaW9uIHN5c3RlbSB0byBrbm93IHdoZXRoZXIgdGhlIG1vZHVsZSBoYXNcbiAqIGFjdHVhbGx5IGhhZCBpdHMgZnJvbnQgYnVuZGxlIGV4ZWN1dGVkIHlldC5cbiAqXG4gKiBUaGlzIHNob3VsZCBvbmx5IGJlIHVzZWQgaW4gZXNtLWFwcC1zaGVsbC5cbiAqXG4gKiBAaW50ZXJuYWxcbiAqIEBwYXJhbSBtb2R1bGVOYW1lXG4gKi8gZXhwb3J0IGZ1bmN0aW9uIHJlZ2lzdGVyTW9kdWxlV2l0aENvbmZpZ1N5c3RlbShtb2R1bGVOYW1lKSB7XG4gICAgY29uZmlnSW50ZXJuYWxTdG9yZS5zZXRTdGF0ZSgoc3RhdGUpPT4oe1xuICAgICAgICAgICAgLi4uc3RhdGUsXG4gICAgICAgICAgICBzY2hlbWFzOiB7XG4gICAgICAgICAgICAgICAgLi4uc3RhdGUuc2NoZW1hcyxcbiAgICAgICAgICAgICAgICBbbW9kdWxlTmFtZV06IGltcGxpY2l0Q29uZmlnU2NoZW1hXG4gICAgICAgICAgICB9XG4gICAgICAgIH0pKTtcbn1cbi8qKlxuICogVGhpcyBhbGVydHMgdGhlIGNvbmZpZ3VyYXRpb24gc3lzdGVtIHRoYXQgYSBtb2R1bGUgaGFzIGJlZW4gbG9hZGVkLlxuICpcbiAqIFRoaXMgc2hvdWxkIG9ubHkgYmUgdXNlZCBpbiBlc20tYXBwLXNoZWxsLlxuICpcbiAqIEBpbnRlcm5hbFxuICogQHBhcmFtIG1vZHVsZU5hbWVcbiAqLyBleHBvcnQgZnVuY3Rpb24gcmVnaXN0ZXJNb2R1bGVMb2FkKG1vZHVsZU5hbWUpIHtcbiAgICBjb25maWdJbnRlcm5hbFN0b3JlLnNldFN0YXRlKChzdGF0ZSk9Pih7XG4gICAgICAgICAgICAuLi5zdGF0ZSxcbiAgICAgICAgICAgIG1vZHVsZUxvYWRlZDoge1xuICAgICAgICAgICAgICAgIC4uLnN0YXRlLm1vZHVsZUxvYWRlZCxcbiAgICAgICAgICAgICAgICBbbW9kdWxlTmFtZV06IHRydWVcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSkpO1xufVxuLyoqXG4gKiBUaGlzIGFsbG93cyB0aGUgY29uZmlnIHN5c3RlbSB0byBzdXBwb3J0IHRyYW5zbGF0aW9uIG92ZXJyaWRlcyBmb3IgbmFtZXNwYWNlcyB0aGF0XG4gKiBkbyBub3QgY29ycmVzcG9uZCB0byBtb2R1bGVzLlxuICpcbiAqIFRoaXMgc2hvdWxkIG9ubHkgYmUgdXNlZCBpbiBlc20tYXBwLXNoZWxsLlxuICpcbiAqIEBpbnRlcm5hbFxuICogQHBhcmFtIG5hbWVzcGFjZVxuICovIGV4cG9ydCBmdW5jdGlvbiByZWdpc3RlclRyYW5zbGF0aW9uTmFtZXNwYWNlKG5hbWVzcGFjZSkge1xuICAgIGNvbmZpZ0ludGVybmFsU3RvcmUuc2V0U3RhdGUoKHN0YXRlKT0+KHtcbiAgICAgICAgICAgIC4uLnN0YXRlLFxuICAgICAgICAgICAgc2NoZW1hczoge1xuICAgICAgICAgICAgICAgIC4uLnN0YXRlLnNjaGVtYXMsXG4gICAgICAgICAgICAgICAgW25hbWVzcGFjZV06IHRyYW5zbGF0aW9uT3ZlcnJpZGVzU2NoZW1hXG4gICAgICAgICAgICB9XG4gICAgICAgIH0pKTtcbn1cbi8qKlxuICogVGhpcyBkZWZpbmVzIGEgY29uZmlndXJhdGlvbiBzY2hlbWEgZm9yIGFuIGV4dGVuc2lvbi4gV2hlbiBhIHNjaGVtYSBpcyBkZWZpbmVkXG4gKiBmb3IgYW4gZXh0ZW5zaW9uLCB0aGF0IGV4dGVuc2lvbiB3aWxsIHJlY2VpdmUgdGhlIGNvbmZpZ3VyYXRpb24gY29ycmVzcG9uZGluZ1xuICogdG8gdGhhdCBzY2hlbWEsIHJhdGhlciB0aGFuIHRoZSBjb25maWd1cmF0aW9uIGNvcnJlc3BvbmRpbmcgdG8gdGhlIG1vZHVsZVxuICogaW4gd2hpY2ggaXQgaXMgZGVmaW5lZC5cbiAqXG4gKiBUaGUgc2NoZW1hIHRlbGxzIHRoZSBjb25maWd1cmF0aW9uIHN5c3RlbSBob3cgdGhlIG1vZHVsZSBjYW4gYmUgY29uZmlndXJlZC5cbiAqIEl0IHNwZWNpZmllcyB3aGF0IG1ha2VzIGNvbmZpZ3VyYXRpb24gdmFsaWQgb3IgaW52YWxpZC5cbiAqXG4gKiBTZWUgW0NvbmZpZ3VyYXRpb24gU3lzdGVtXShodHRwczovL28zLWRvY3Mub3Blbm1ycy5vcmcvZG9jcy9jb25maWd1cmF0aW9uLXN5c3RlbSlcbiAqIGZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IGRlZmluaW5nIGEgY29uZmlnIHNjaGVtYS5cbiAqXG4gKiBAcGFyYW0gZXh0ZW5zaW9uTmFtZSBOYW1lIG9mIHRoZSBleHRlbnNpb24gdGhlIHNjaGVtYSBpcyBiZWluZyBkZWZpbmVkIGZvci5cbiAqICAgU2hvdWxkIG1hdGNoIHRoZSBgbmFtZWAgb2Ygb25lIG9mIHRoZSBgZXh0ZW5zaW9uc2AgZW50cmllcyBiZWluZyByZXR1cm5lZFxuICogICBieSBgc2V0dXBPcGVuTVJTYC5cbiAqIEBwYXJhbSBzY2hlbWEgVGhlIGNvbmZpZyBzY2hlbWEgZm9yIHRoZSBleHRlbnNpb25cbiAqLyBleHBvcnQgZnVuY3Rpb24gZGVmaW5lRXh0ZW5zaW9uQ29uZmlnU2NoZW1hKGV4dGVuc2lvbk5hbWUsIHNjaGVtYSkge1xuICAgIHZhbGlkYXRlQ29uZmlnU2NoZW1hKGV4dGVuc2lvbk5hbWUsIHNjaGVtYSk7XG4gICAgY29uc3QgZW5oYW5jZWRTY2hlbWEgPSBtZXJnZURlZXBSaWdodChzY2hlbWEsIGltcGxpY2l0Q29uZmlnU2NoZW1hKTtcbiAgICBjb25zdCBzdGF0ZSA9IGNvbmZpZ0ludGVybmFsU3RvcmUuZ2V0U3RhdGUoKTtcbiAgICBpZiAoc3RhdGUuc2NoZW1hc1tleHRlbnNpb25OYW1lXSkge1xuICAgICAgICBjb25zb2xlLmVycm9yKGBDb25maWcgc2NoZW1hIGZvciBleHRlbnNpb24gJHtleHRlbnNpb25OYW1lfSBhbHJlYWR5IGV4aXN0cy4gSWYgdGhlcmUgYXJlIG11bHRpcGxlIGV4dGVuc2lvbnMgd2l0aCB0aGlzIHNhbWUgbmFtZSwgb25lIHdpbGwgcHJvYmFibHkgY3Jhc2guYCk7XG4gICAgfVxuICAgIGNvbmZpZ0ludGVybmFsU3RvcmUuc2V0U3RhdGUoKHN0YXRlKT0+KHtcbiAgICAgICAgICAgIC4uLnN0YXRlLFxuICAgICAgICAgICAgc2NoZW1hczoge1xuICAgICAgICAgICAgICAgIC4uLnN0YXRlLnNjaGVtYXMsXG4gICAgICAgICAgICAgICAgW2V4dGVuc2lvbk5hbWVdOiBlbmhhbmNlZFNjaGVtYVxuICAgICAgICAgICAgfVxuICAgICAgICB9KSk7XG59XG5leHBvcnQgZnVuY3Rpb24gcHJvdmlkZShjb25maWcsIHNvdXJjZU5hbWUgPSAncHJvdmlkZWQnKSB7XG4gICAgY29uZmlnSW50ZXJuYWxTdG9yZS5zZXRTdGF0ZSgoc3RhdGUpPT4oe1xuICAgICAgICAgICAgLi4uc3RhdGUsXG4gICAgICAgICAgICBwcm92aWRlZENvbmZpZ3M6IFtcbiAgICAgICAgICAgICAgICAuLi5zdGF0ZS5wcm92aWRlZENvbmZpZ3MsXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBzb3VyY2U6IHNvdXJjZU5hbWUsXG4gICAgICAgICAgICAgICAgICAgIGNvbmZpZ1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIF1cbiAgICAgICAgfSkpO1xufVxuLyoqXG4gKiBBIHByb21pc2UtYmFzZWQgd2F5IHRvIGFjY2VzcyB0aGUgY29uZmlnIGFzIHNvb24gYXMgaXQgaXMgZnVsbHkgbG9hZGVkLlxuICogSWYgaXQgaXMgYWxyZWFkeSBsb2FkZWQsIHJlc29sdmVzIHRoZSBjb25maWcgaW4gaXRzIHByZXNlbnQgc3RhdGUuXG4gKlxuICogVGhpcyBpcyBhIHVzZWZ1bCBmdW5jdGlvbiBpZiB5b3UgbmVlZCB0byBnZXQgdGhlIGNvbmZpZyBpbiB0aGUgY291cnNlXG4gKiBvZiB0aGUgZXhlY3V0aW9uIG9mIGEgZnVuY3Rpb24uXG4gKlxuICogQHBhcmFtIG1vZHVsZU5hbWUgVGhlIG5hbWUgb2YgdGhlIG1vZHVsZSBmb3Igd2hpY2ggdG8gbG9vayB1cCB0aGUgY29uZmlnXG4gKi8gZXhwb3J0IGZ1bmN0aW9uIGdldENvbmZpZyhtb2R1bGVOYW1lKSB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlKT0+e1xuICAgICAgICBjb25zdCBzdG9yZSA9IGdldENvbmZpZ1N0b3JlKG1vZHVsZU5hbWUpO1xuICAgICAgICBmdW5jdGlvbiB1cGRhdGUoc3RhdGUpIHtcbiAgICAgICAgICAgIGlmIChzdGF0ZS5sb2FkZWQgJiYgc3RhdGUuY29uZmlnKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgY29uZmlnID0gb21pdChbXG4gICAgICAgICAgICAgICAgICAgICdEaXNwbGF5IGNvbmRpdGlvbnMnLFxuICAgICAgICAgICAgICAgICAgICAnVHJhbnNsYXRpb24gb3ZlcnJpZGVzJ1xuICAgICAgICAgICAgICAgIF0sIHN0YXRlLmNvbmZpZyk7XG4gICAgICAgICAgICAgICAgcmVzb2x2ZShjb25maWcpO1xuICAgICAgICAgICAgICAgIGlmICh1bnN1YnNjcmliZSkge1xuICAgICAgICAgICAgICAgICAgICB1bnN1YnNjcmliZSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB1cGRhdGUoc3RvcmUuZ2V0U3RhdGUoKSk7XG4gICAgICAgIGNvbnN0IHVuc3Vic2NyaWJlID0gc3RvcmUuc3Vic2NyaWJlKHVwZGF0ZSk7XG4gICAgfSk7XG59XG4vKiogQGludGVybmFsICovIGV4cG9ydCBmdW5jdGlvbiBnZXRUcmFuc2xhdGlvbk92ZXJyaWRlcyhtb2R1bGVOYW1lLCBzbG90TmFtZSwgZXh0ZW5zaW9uSWQpIHtcbiAgICBjb25zdCBwcm9taXNlcyA9IFtcbiAgICAgICAgbmV3IFByb21pc2UoKHJlc29sdmUpPT57XG4gICAgICAgICAgICBjb25zdCBjb25maWdTdG9yZSA9IGdldENvbmZpZ1N0b3JlKG1vZHVsZU5hbWUpO1xuICAgICAgICAgICAgZnVuY3Rpb24gdXBkYXRlKHN0YXRlKSB7XG4gICAgICAgICAgICAgICAgaWYgKHN0YXRlLnRyYW5zbGF0aW9uT3ZlcnJpZGVzTG9hZGVkICYmIHN0YXRlLmNvbmZpZykge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCB0cmFuc2xhdGlvbk92ZXJyaWRlcyA9IHN0YXRlLmNvbmZpZ1snVHJhbnNsYXRpb24gb3ZlcnJpZGVzJ10gPz8ge307XG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUodHJhbnNsYXRpb25PdmVycmlkZXMpO1xuICAgICAgICAgICAgICAgICAgICBpZiAodW5zdWJzY3JpYmUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHVuc3Vic2NyaWJlKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB1cGRhdGUoY29uZmlnU3RvcmUuZ2V0U3RhdGUoKSk7XG4gICAgICAgICAgICBjb25zdCB1bnN1YnNjcmliZSA9IGNvbmZpZ1N0b3JlLnN1YnNjcmliZSh1cGRhdGUpO1xuICAgICAgICB9KVxuICAgIF07XG4gICAgaWYgKHNsb3ROYW1lICYmIGV4dGVuc2lvbklkKSB7XG4gICAgICAgIHByb21pc2VzLnB1c2gobmV3IFByb21pc2UoKHJlc29sdmUpPT57XG4gICAgICAgICAgICBjb25zdCBjb25maWdTdG9yZSA9IGdldEV4dGVuc2lvbkNvbmZpZyhzbG90TmFtZSwgZXh0ZW5zaW9uSWQpO1xuICAgICAgICAgICAgZnVuY3Rpb24gdXBkYXRlKHN0YXRlKSB7XG4gICAgICAgICAgICAgICAgaWYgKHN0YXRlLmxvYWRlZCAmJiBzdGF0ZS5jb25maWcpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdHJhbnNsYXRpb25PdmVycmlkZXMgPSBzdGF0ZS5jb25maWdbJ1RyYW5zbGF0aW9uIG92ZXJyaWRlcyddID8/IHt9O1xuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHRyYW5zbGF0aW9uT3ZlcnJpZGVzKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHVuc3Vic2NyaWJlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB1bnN1YnNjcmliZSgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdXBkYXRlKGNvbmZpZ1N0b3JlLmdldFN0YXRlKCkpO1xuICAgICAgICAgICAgY29uc3QgdW5zdWJzY3JpYmUgPSBjb25maWdTdG9yZS5zdWJzY3JpYmUodXBkYXRlKTtcbiAgICAgICAgfSkpO1xuICAgIH1cbiAgICByZXR1cm4gUHJvbWlzZS5hbGwocHJvbWlzZXMpO1xufVxuLyoqXG4gKiBWYWxpZGF0ZSBhbmQgaW50ZXJwb2xhdGUgZGVmYXVsdHMgZm9yIGBwcm92aWRlZENvbmZpZ2AgYWNjb3JkaW5nIHRvIGBzY2hlbWFgXG4gKlxuICogQHBhcmFtIHNjaGVtYSAgYSBjb25maWd1cmF0aW9uIHNjaGVtYVxuICogQHBhcmFtIHByb3ZpZGVkQ29uZmlnICBhbiBvYmplY3Qgb2YgY29uZmlnIHZhbHVlcyAod2l0aG91dCB0aGUgdG9wLWxldmVsIG1vZHVsZSBuYW1lKVxuICogQHBhcmFtIGtleVBhdGhDb250ZXh0ICBhIGRvdC1kZXBhcmF0ZWQgc3RyaW5nIHdoaWNoIGhlbHBzIHRoZSB1c2VyIGZpZ3VyZSBvdXQgd2hlcmVcbiAqICAgICB0aGUgcHJvdmlkZWQgY29uZmlnIGNhbWUgZnJvbVxuICogQGludGVybmFsXG4gKi8gZXhwb3J0IGZ1bmN0aW9uIHByb2Nlc3NDb25maWcoc2NoZW1hLCBwcm92aWRlZENvbmZpZywga2V5UGF0aENvbnRleHQpIHtcbiAgICB2YWxpZGF0ZVN0cnVjdHVyZShzY2hlbWEsIHByb3ZpZGVkQ29uZmlnLCBrZXlQYXRoQ29udGV4dCk7XG4gICAgY29uc3QgY29uZmlnID0gc2V0RGVmYXVsdHMoc2NoZW1hLCBwcm92aWRlZENvbmZpZyk7XG4gICAgcnVuQWxsVmFsaWRhdG9yc0luQ29uZmlnVHJlZShzY2hlbWEsIGNvbmZpZywga2V5UGF0aENvbnRleHQpO1xuICAgIHJldHVybiBjb25maWc7XG59XG4vKlxuICogSGVscGVyIGZ1bmN0aW9uc1xuICpcbiAqLyAvKipcbiAqIFJldHVybnMgdGhlIGNvbmZpZ3VyYXRpb24gZm9yIGFuIGV4dGVuc2lvbi4gVGhpcyBjb25maWd1cmF0aW9uIGlzIHNwZWNpZmljXG4gKiB0byB0aGUgc2xvdCBpbiB3aGljaCBpdCBpcyBtb3VudGVkLCBhbmQgaXRzIElEIHdpdGhpbiB0aGF0IHNsb3QuXG4gKlxuICogVGhlIHNjaGVtYSBmb3IgdGhhdCBjb25maWd1cmF0aW9uIGlzIHRoZSBleHRlbnNpb24gc2NoZW1hLiBJZiBubyBleHRlbnNpb25cbiAqIHNjaGVtYSBoYXMgYmVlbiBwcm92aWRlZCwgdGhlIHNjaGVtYSB1c2VkIGlzIHRoZSBzY2hlbWEgb2YgdGhlIG1vZHVsZSBpblxuICogd2hpY2ggdGhlIGV4dGVuc2lvbiBpcyBkZWZpbmVkLlxuICpcbiAqIEBwYXJhbSBzbG90TW9kdWxlTmFtZSBUaGUgbmFtZSBvZiB0aGUgbW9kdWxlIHdoaWNoIGRlZmluZXMgdGhlIGV4dGVuc2lvbiBzbG90XG4gKiBAcGFyYW0gZXh0ZW5zaW9uTW9kdWxlTmFtZSBUaGUgbmFtZSBvZiB0aGUgbW9kdWxlIHdoaWNoIGRlZmluZXMgdGhlIGV4dGVuc2lvbiAoYW5kIHRoZXJlZm9yZSB0aGUgY29uZmlnIHNjaGVtYSlcbiAqIEBwYXJhbSBzbG90TmFtZSBUaGUgbmFtZSBvZiB0aGUgZXh0ZW5zaW9uIHNsb3Qgd2hlcmUgdGhlIGV4dGVuc2lvbiBpcyBtb3VudGVkXG4gKiBAcGFyYW0gZXh0ZW5zaW9uSWQgVGhlIElEIG9mIHRoZSBleHRlbnNpb24gaW4gaXRzIHNsb3RcbiAqLyBmdW5jdGlvbiBjb21wdXRlRXh0ZW5zaW9uQ29uZmlnKHNsb3RNb2R1bGVOYW1lLCBleHRlbnNpb25Nb2R1bGVOYW1lLCBzbG90TmFtZSwgZXh0ZW5zaW9uSWQsIGNvbmZpZ1N0YXRlLCB0ZW1wQ29uZmlnU3RhdGUpIHtcbiAgICBjb25zdCBleHRlbnNpb25OYW1lID0gZ2V0RXh0ZW5zaW9uTmFtZUZyb21JZChleHRlbnNpb25JZCk7XG4gICAgY29uc3QgZXh0ZW5zaW9uQ29uZmlnU2NoZW1hID0gY29uZmlnU3RhdGUuc2NoZW1hc1tleHRlbnNpb25OYW1lXTtcbiAgICBjb25zdCBuYW1lT2ZTY2hlbWFTb3VyY2UgPSBleHRlbnNpb25Db25maWdTY2hlbWEgPyBleHRlbnNpb25OYW1lIDogZXh0ZW5zaW9uTW9kdWxlTmFtZTtcbiAgICBjb25zdCBwcm92aWRlZENvbmZpZ3MgPSBnZXRQcm92aWRlZENvbmZpZ3MoY29uZmlnU3RhdGUsIHRlbXBDb25maWdTdGF0ZSk7XG4gICAgY29uc3Qgc2xvdE1vZHVsZUNvbmZpZyA9IG1lcmdlQ29uZmlnc0ZvcihzbG90TW9kdWxlTmFtZSwgcHJvdmlkZWRDb25maWdzKTtcbiAgICBjb25zdCBjb25maWdPdmVycmlkZSA9IHNsb3RNb2R1bGVDb25maWc/LmV4dGVuc2lvblNsb3RzPy5bc2xvdE5hbWVdPy5jb25maWd1cmU/LltleHRlbnNpb25JZF0gPz8ge307XG4gICAgY29uc3QgZXh0ZW5zaW9uQ29uZmlnID0gbWVyZ2VDb25maWdzRm9yKG5hbWVPZlNjaGVtYVNvdXJjZSwgcHJvdmlkZWRDb25maWdzKTtcbiAgICBjb25zdCBjb21iaW5lZENvbmZpZyA9IG1lcmdlQ29uZmlncyhbXG4gICAgICAgIGV4dGVuc2lvbkNvbmZpZyxcbiAgICAgICAgY29uZmlnT3ZlcnJpZGVcbiAgICBdKTtcbiAgICBjb25zdCBzY2hlbWEgPSBleHRlbnNpb25Db25maWdTY2hlbWEgPz8gY29uZmlnU3RhdGUuc2NoZW1hc1tleHRlbnNpb25Nb2R1bGVOYW1lXTtcbiAgICB2YWxpZGF0ZVN0cnVjdHVyZShzY2hlbWEsIGNvbWJpbmVkQ29uZmlnLCBuYW1lT2ZTY2hlbWFTb3VyY2UpO1xuICAgIGNvbnN0IGNvbmZpZyA9IHNldERlZmF1bHRzKHNjaGVtYSwgY29tYmluZWRDb25maWcpO1xuICAgIHJ1bkFsbFZhbGlkYXRvcnNJbkNvbmZpZ1RyZWUoc2NoZW1hLCBjb25maWcsIG5hbWVPZlNjaGVtYVNvdXJjZSk7XG4gICAgZGVsZXRlIGNvbmZpZy5leHRlbnNpb25TbG90cztcbiAgICByZXR1cm4gY29uZmlnO1xufVxuZnVuY3Rpb24gZ2V0SW1wbGVtZW50ZXJUb29sc0NvbmZpZyhjb25maWdTdGF0ZSwgdGVtcENvbmZpZ1N0YXRlKSB7XG4gICAgbGV0IHJlc3VsdCA9IGdldFNjaGVtYVdpdGhWYWx1ZXNBbmRTb3VyY2VzKGNsb25lKGNvbmZpZ1N0YXRlLnNjaGVtYXMpKTtcbiAgICBjb25zdCBjb25maWdzQW5kU291cmNlcyA9IFtcbiAgICAgICAgLi4uY29uZmlnU3RhdGUucHJvdmlkZWRDb25maWdzLm1hcCgoYyk9PltcbiAgICAgICAgICAgICAgICBjLmNvbmZpZyxcbiAgICAgICAgICAgICAgICBjLnNvdXJjZVxuICAgICAgICAgICAgXSksXG4gICAgICAgIFtcbiAgICAgICAgICAgIHRlbXBDb25maWdTdGF0ZS5jb25maWcsXG4gICAgICAgICAgICAndGVtcG9yYXJ5IGNvbmZpZydcbiAgICAgICAgXVxuICAgIF07XG4gICAgZm9yIChsZXQgW2NvbmZpZywgc291cmNlXSBvZiBjb25maWdzQW5kU291cmNlcyl7XG4gICAgICAgIHJlc3VsdCA9IG1lcmdlQ29uZmlncyhbXG4gICAgICAgICAgICByZXN1bHQsXG4gICAgICAgICAgICBjcmVhdGVWYWx1ZXNBbmRTb3VyY2VzVHJlZShjb25maWcsIHNvdXJjZSlcbiAgICAgICAgXSk7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG59XG5mdW5jdGlvbiBnZXRTY2hlbWFXaXRoVmFsdWVzQW5kU291cmNlcyhzY2hlbWEpIHtcbiAgICBpZiAoc2NoZW1hLmhhc093blByb3BlcnR5KCdfZGVmYXVsdCcpKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAuLi5zY2hlbWEsXG4gICAgICAgICAgICBfdmFsdWU6IHNjaGVtYS5fZGVmYXVsdCxcbiAgICAgICAgICAgIF9zb3VyY2U6ICdkZWZhdWx0J1xuICAgICAgICB9O1xuICAgIH0gZWxzZSBpZiAoaXNPcmRpbmFyeU9iamVjdChzY2hlbWEpKSB7XG4gICAgICAgIHJldHVybiBPYmplY3Qua2V5cyhzY2hlbWEpLnJlZHVjZSgob2JqLCBrZXkpPT57XG4gICAgICAgICAgICBvYmpba2V5XSA9IGdldFNjaGVtYVdpdGhWYWx1ZXNBbmRTb3VyY2VzKHNjaGVtYVtrZXldKTtcbiAgICAgICAgICAgIHJldHVybiBvYmo7XG4gICAgICAgIH0sIHt9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgICAvLyBhdCB0aGlzIHBvaW50LCB0aGUgc2NoZW1hIGlzIGJhZCBhbmQgYW4gZXJyb3Igd2lsbCBoYXZlIGJlZW4gbG9nZ2VkIGR1cmluZyBzY2hlbWEgdmFsaWRhdGlvblxuICAgICAgICByZXR1cm4ge307XG4gICAgfVxufVxuZnVuY3Rpb24gY3JlYXRlVmFsdWVzQW5kU291cmNlc1RyZWUoY29uZmlnLCBzb3VyY2UpIHtcbiAgICBpZiAoaXNPcmRpbmFyeU9iamVjdChjb25maWcpKSB7XG4gICAgICAgIHJldHVybiBPYmplY3Qua2V5cyhjb25maWcpLnJlZHVjZSgob2JqLCBrZXkpPT57XG4gICAgICAgICAgICBvYmpba2V5XSA9IGNyZWF0ZVZhbHVlc0FuZFNvdXJjZXNUcmVlKGNvbmZpZ1trZXldLCBzb3VyY2UpO1xuICAgICAgICAgICAgcmV0dXJuIG9iajtcbiAgICAgICAgfSwge30pO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBfdmFsdWU6IGNvbmZpZyxcbiAgICAgICAgICAgIF9zb3VyY2U6IHNvdXJjZVxuICAgICAgICB9O1xuICAgIH1cbn1cbmZ1bmN0aW9uIGdldEV4dGVuc2lvblNsb3RDb25maWdzKGNvbmZpZ1N0YXRlLCB0ZW1wQ29uZmlnU3RhdGUpIHtcbiAgICBjb25zdCBhbGxDb25maWdzID0gbWVyZ2VDb25maWdzKGdldFByb3ZpZGVkQ29uZmlncyhjb25maWdTdGF0ZSwgdGVtcENvbmZpZ1N0YXRlKSk7XG4gICAgY29uc3Qgc2xvdENvbmZpZ1Blck1vZHVsZSA9IE9iamVjdC5rZXlzKGFsbENvbmZpZ3MpLnJlZHVjZSgob2JqLCBrZXkpPT57XG4gICAgICAgIGlmIChhbGxDb25maWdzW2tleV0/LmV4dGVuc2lvblNsb3RzKSB7XG4gICAgICAgICAgICBvYmpba2V5XSA9IGFsbENvbmZpZ3Nba2V5XT8uZXh0ZW5zaW9uU2xvdHM7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG9iajtcbiAgICB9LCB7fSk7XG4gICAgdmFsaWRhdGVBbGxFeHRlbnNpb25TbG90Q29uZmlncyhzbG90Q29uZmlnUGVyTW9kdWxlKTtcbiAgICBjb25zdCBzbG90Q29uZmlncyA9IE9iamVjdC5rZXlzKHNsb3RDb25maWdQZXJNb2R1bGUpLnJlZHVjZSgob2JqLCBrZXkpPT57XG4gICAgICAgIG9iaiA9IHtcbiAgICAgICAgICAgIC4uLm9iaixcbiAgICAgICAgICAgIC4uLnNsb3RDb25maWdQZXJNb2R1bGVba2V5XVxuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gb2JqO1xuICAgIH0sIHt9KTtcbiAgICByZXR1cm4gc2xvdENvbmZpZ3M7XG59XG5mdW5jdGlvbiB2YWxpZGF0ZUFsbEV4dGVuc2lvblNsb3RDb25maWdzKHNsb3RDb25maWdQZXJNb2R1bGUpIHtcbiAgICBmb3IgKGxldCBbbW9kdWxlTmFtZSwgY29uZmlnQnlTbG90TmFtZV0gb2YgT2JqZWN0LmVudHJpZXMoc2xvdENvbmZpZ1Blck1vZHVsZSkpe1xuICAgICAgICBmb3IgKGxldCBbc2xvdE5hbWUsIGNvbmZpZ10gb2YgT2JqZWN0LmVudHJpZXMoY29uZmlnQnlTbG90TmFtZSkpe1xuICAgICAgICAgICAgdmFsaWRhdGVFeHRlbnNpb25TbG90Q29uZmlnKGNvbmZpZywgbW9kdWxlTmFtZSwgc2xvdE5hbWUpO1xuICAgICAgICB9XG4gICAgfVxufVxuZnVuY3Rpb24gdmFsaWRhdGVFeHRlbnNpb25TbG90Q29uZmlnKGNvbmZpZywgbW9kdWxlTmFtZSwgc2xvdE5hbWUpIHtcbiAgICBjb25zdCBrZXlQYXRoID0gYCR7bW9kdWxlTmFtZX0uZXh0ZW5zaW9uU2xvdHMuJHtzbG90TmFtZX1gO1xuICAgIGNvbnN0IGVycm9yUHJlZml4ID0gYEV4dGVuc2lvbiBzbG90IGNvbmZpZyAnJHtrZXlQYXRofSdgO1xuICAgIGNvbnN0IGludmFsaWRLZXlzID0gT2JqZWN0LmtleXMoY29uZmlnKS5maWx0ZXIoKGspPT4hW1xuICAgICAgICAgICAgJ2FkZCcsXG4gICAgICAgICAgICAncmVtb3ZlJyxcbiAgICAgICAgICAgICdvcmRlcicsXG4gICAgICAgICAgICAnY29uZmlndXJlJ1xuICAgICAgICBdLmluY2x1ZGVzKGspKTtcbiAgICBpZiAoaW52YWxpZEtleXMubGVuZ3RoKSB7XG4gICAgICAgIGxvZ0Vycm9yKGtleVBhdGgsIGVycm9yUHJlZml4ICsgYCcgY29udGFpbnMgaW52YWxpZCBrZXlzICcke2ludmFsaWRLZXlzLmpvaW4oXCInLCAnXCIpfSdgKTtcbiAgICB9XG4gICAgaWYgKGNvbmZpZy5hZGQpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KGNvbmZpZy5hZGQpIHx8ICFjb25maWcuYWRkLmV2ZXJ5KChuKT0+dHlwZW9mIG4gPT09ICdzdHJpbmcnKSkge1xuICAgICAgICAgICAgbG9nRXJyb3Ioa2V5UGF0aCwgZXJyb3JQcmVmaXggKyBgLmFkZCcgaXMgaW52YWxpZC4gTXVzdCBiZSBhbiBhcnJheSBvZiBzdHJpbmdzIChleHRlbnNpb24gSURzKWApO1xuICAgICAgICB9XG4gICAgfVxuICAgIGlmIChjb25maWcucmVtb3ZlKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShjb25maWcucmVtb3ZlKSB8fCAhY29uZmlnLnJlbW92ZS5ldmVyeSgobik9PnR5cGVvZiBuID09PSAnc3RyaW5nJykpIHtcbiAgICAgICAgICAgIGxvZ0Vycm9yKGtleVBhdGgsIGVycm9yUHJlZml4ICsgYC5yZW1vdmUnIGlzIGludmFsaWQuIE11c3QgYmUgYW4gYXJyYXkgb2Ygc3RyaW5ncyAoZXh0ZW5zaW9uIElEcylgKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBpZiAoY29uZmlnLm9yZGVyKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShjb25maWcub3JkZXIpIHx8ICFjb25maWcub3JkZXIuZXZlcnkoKG4pPT50eXBlb2YgbiA9PT0gJ3N0cmluZycpKSB7XG4gICAgICAgICAgICBsb2dFcnJvcihrZXlQYXRoLCBlcnJvclByZWZpeCArIGAub3JkZXInIGlzIGludmFsaWQuIE11c3QgYmUgYW4gYXJyYXkgb2Ygc3RyaW5ncyAoZXh0ZW5zaW9uIElEcylgKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBpZiAoY29uZmlnLmNvbmZpZ3VyZSkge1xuICAgICAgICBpZiAoIWlzT3JkaW5hcnlPYmplY3QoY29uZmlnLmNvbmZpZ3VyZSkpIHtcbiAgICAgICAgICAgIGxvZ0Vycm9yKGtleVBhdGgsIGVycm9yUHJlZml4ICsgYC5jb25maWd1cmUnIGlzIGludmFsaWQuIE11c3QgYmUgYW4gb2JqZWN0IHdpdGggZXh0ZW5zaW9uIElEcyBmb3Iga2V5c2ApO1xuICAgICAgICB9XG4gICAgfVxufVxuZnVuY3Rpb24gZ2V0UHJvdmlkZWRDb25maWdzKGNvbmZpZ1N0YXRlLCB0ZW1wQ29uZmlnU3RhdGUpIHtcbiAgICByZXR1cm4gW1xuICAgICAgICAuLi5jb25maWdTdGF0ZS5wcm92aWRlZENvbmZpZ3MubWFwKChjKT0+Yy5jb25maWcpLFxuICAgICAgICB0ZW1wQ29uZmlnU3RhdGUuY29uZmlnXG4gICAgXTtcbn1cbi8qKlxuICogVmFsaWRhdGVzIHRoZSBjb25maWcgc2NoZW1hIGZvciBhIG1vZHVsZS4gU2luY2UgcHJvYmxlbXMgaWRlbnRpZmllZCBoZXJlIGFyZSBwcm9ncmFtbWluZyBlcnJvcnNcbiAqIHRoYXQgaG9wZWZ1bGx5IHdpbGwgYmUgY2F1Z2h0IGR1cmluZyBkZXZlbG9wbWVudCwgdGhpcyBmdW5jdGlvbiBsb2dzIGVycm9ycyB0byB0aGUgY29uc29sZSBkaXJlY3RseTtcbiAqIGl0J3MgZmluZSBpZiB3ZSBzcGFtIHRoZSB1c2VyIHdpdGggdGhlc2UgZXJyb3JzLlxuICovIGZ1bmN0aW9uIHZhbGlkYXRlQ29uZmlnU2NoZW1hKG1vZHVsZU5hbWUsIHNjaGVtYSwga2V5UGF0aCA9ICcnKSB7XG4gICAgY29uc3QgdXBkYXRlTWVzc2FnZSA9IGBQbGVhc2UgdmVyaWZ5IHRoYXQgeW91IGFyZSBydW5uaW5nIHRoZSBsYXRlc3QgdmVyc2lvbiBhbmQsIGlmIHNvLCBhbGVydCB0aGUgbWFpbnRhaW5lci5gO1xuICAgIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKHNjaGVtYSkuZmlsdGVyKChrKT0+IWsuc3RhcnRzV2l0aCgnXycpKSl7XG4gICAgICAgIGNvbnN0IHRoaXNLZXlQYXRoID0ga2V5UGF0aCArIChrZXlQYXRoICYmICcuJykgKyBrZXk7XG4gICAgICAgIGNvbnN0IHNjaGVtYVBhcnQgPSBzY2hlbWFba2V5XTtcbiAgICAgICAgaWYgKHRoaXNLZXlQYXRoID09PSAnRGlzcGxheSBjb25kaXRpb25zJykge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcihgJHttb2R1bGVOYW1lfSBkZWNsYXJlcyBhIGNvbmZpZ3VyYXRpb24gb3B0aW9uIGNhbGxlZCBcIkRpc3BsYXkgY29uZGl0aW9uc1wiOyB0aGUgXCJEaXNwbGF5IGNvbmRpdGlvbnNcIiBvcHRpb24gaXMgYSByZXNlcnZlZCBuYW1lLiAke3VwZGF0ZU1lc3NhZ2V9YCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXNLZXlQYXRoID09PSAnVHJhbnNsYXRpb24gb3ZlcnJpZGVzJykge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcihgJHttb2R1bGVOYW1lfSBkZWNsYXJlcyBhIGNvbmZpZ3VyYXRpb24gb3B0aW9uIGNhbGxlZCBcIlRyYW5zbGF0aW9uIG92ZXJyaWRlc1wiOyB0aGUgXCJUcmFuc2xhdGlvbiBvdmVycmlkZXNcIiBvcHRpb24gaXMgYSByZXNlcnZlZCBuYW1lLiAke3VwZGF0ZU1lc3NhZ2V9YCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFpc09yZGluYXJ5T2JqZWN0KHNjaGVtYVBhcnQpKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKGAke21vZHVsZU5hbWV9IGhhcyBiYWQgY29uZmlnIHNjaGVtYSBkZWZpbml0aW9uIGZvciBrZXkgJyR7dGhpc0tleVBhdGh9Jy4gJHt1cGRhdGVNZXNzYWdlfWApO1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFzY2hlbWFQYXJ0Lmhhc093blByb3BlcnR5KCdfZGVmYXVsdCcpKSB7XG4gICAgICAgICAgICAvLyByZWN1cnNlIGZvciBuZXN0ZWQgY29uZmlnIGtleXNcbiAgICAgICAgICAgIHZhbGlkYXRlQ29uZmlnU2NoZW1hKG1vZHVsZU5hbWUsIHNjaGVtYVBhcnQsIHRoaXNLZXlQYXRoKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBlbGVtZW50cyA9IHNjaGVtYVBhcnQuX2VsZW1lbnRzO1xuICAgICAgICBpZiAoaGFzT2JqZWN0U2NoZW1hKGVsZW1lbnRzKSkge1xuICAgICAgICAgICAgdmFsaWRhdGVDb25maWdTY2hlbWEobW9kdWxlTmFtZSwgZWxlbWVudHMsIHRoaXNLZXlQYXRoICsgJy5fZWxlbWVudHMnKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoc2NoZW1hUGFydC5fdmFsaWRhdG9ycykge1xuICAgICAgICAgICAgZm9yIChsZXQgdmFsaWRhdG9yIG9mIHNjaGVtYVBhcnQuX3ZhbGlkYXRvcnMpe1xuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgdmFsaWRhdG9yICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYCR7bW9kdWxlTmFtZX0gaGFzIGludmFsaWQgdmFsaWRhdG9yIGZvciBrZXkgJyR7dGhpc0tleVBhdGh9JyAke3VwZGF0ZU1lc3NhZ2V9LmAgKyBgXFxuXFxuSWYgeW91J3JlIHRoZSBtYWludGFpbmVyOiB2YWxpZGF0b3JzIG11c3QgYmUgZnVuY3Rpb25zIHRoYXQgcmV0dXJuIGVpdGhlciBgICsgYHVuZGVmaW5lZCBvciBhbiBlcnJvciBzdHJpbmcuIFJlY2VpdmVkICR7dmFsaWRhdG9yfS5gKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgdmFsdWVUeXBlID0gc2NoZW1hUGFydC5fdHlwZTtcbiAgICAgICAgaWYgKHZhbHVlVHlwZSAmJiAhT2JqZWN0LnZhbHVlcyhUeXBlKS5pbmNsdWRlcyh2YWx1ZVR5cGUpKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKGAke21vZHVsZU5hbWV9IGhhcyBpbnZhbGlkIHR5cGUgZm9yIGtleSAnJHt0aGlzS2V5UGF0aH0nICR7dXBkYXRlTWVzc2FnZX0uYCArIGBcXG5cXG5JZiB5b3UncmUgdGhlIG1haW50YWluZXI6IHRoZSBhbGxvd2VkIHR5cGVzIGFyZSAke09iamVjdC52YWx1ZXMoVHlwZSkuam9pbignLCAnKX0uIGAgKyBgUmVjZWl2ZWQgJyR7dmFsdWVUeXBlfSdgKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoT2JqZWN0LmtleXMoc2NoZW1hUGFydCkuZXZlcnkoKGspPT5bXG4gICAgICAgICAgICAgICAgJ19kZXNjcmlwdGlvbicsXG4gICAgICAgICAgICAgICAgJ192YWxpZGF0b3JzJyxcbiAgICAgICAgICAgICAgICAnX2VsZW1lbnRzJyxcbiAgICAgICAgICAgICAgICAnX3R5cGUnXG4gICAgICAgICAgICBdLmluY2x1ZGVzKGspKSAmJiAha2V5UGF0aC5pbmNsdWRlcygnLl9lbGVtZW50cycpKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKGAke21vZHVsZU5hbWV9IGhhcyBiYWQgY29uZmlnIHNjaGVtYSBkZWZpbml0aW9uIGZvciBrZXkgJyR7dGhpc0tleVBhdGh9Jy4gJHt1cGRhdGVNZXNzYWdlfS5gICsgYFxcblxcbklmIHlvdSdyZSB0aGUgbWFpbnRhaW5lcjogYWxsIGNvbmZpZyBlbGVtZW50cyBtdXN0IGhhdmUgYSBkZWZhdWx0LiBgICsgYFJlY2VpdmVkICR7SlNPTi5zdHJpbmdpZnkoc2NoZW1hUGFydCl9YCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGVsZW1lbnRzICYmIHZhbHVlVHlwZSAmJiAhW1xuICAgICAgICAgICAgVHlwZS5BcnJheSxcbiAgICAgICAgICAgIFR5cGUuT2JqZWN0XG4gICAgICAgIF0uaW5jbHVkZXModmFsdWVUeXBlKSkge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcihgJHttb2R1bGVOYW1lfSBoYXMgYmFkIGNvbmZpZyBzY2hlbWEgZGVmaW5pdGlvbiBmb3Iga2V5ICcke3RoaXNLZXlQYXRofScuICR7dXBkYXRlTWVzc2FnZX0uYCArIGBcXG5cXG5JZiB5b3UncmUgdGhlIG1haW50YWluZXI6IHRoZSAnZWxlbWVudHMnIGtleSBvbmx5IHdvcmtzIHdpdGggJ190eXBlJyBlcXVhbCB0byAnQXJyYXknIG9yICdPYmplY3QnLiBgICsgYFJlY2VpdmVkICR7SlNPTi5zdHJpbmdpZnkodmFsdWVUeXBlKX1gKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbmZ1bmN0aW9uIGdldENvbmZpZ0Zvck1vZHVsZShtb2R1bGVOYW1lLCBjb25maWdTdGF0ZSwgdGVtcENvbmZpZ1N0YXRlKSB7XG4gICAgY29uc3Qgc2NoZW1hID0gY29uZmlnU3RhdGUuc2NoZW1hc1ttb2R1bGVOYW1lXTtcbiAgICBjb25zdCBpbnB1dENvbmZpZyA9IG1lcmdlQ29uZmlnc0Zvcihtb2R1bGVOYW1lLCBnZXRQcm92aWRlZENvbmZpZ3MoY29uZmlnU3RhdGUsIHRlbXBDb25maWdTdGF0ZSkpO1xuICAgIHZhbGlkYXRlU3RydWN0dXJlKHNjaGVtYSwgaW5wdXRDb25maWcsIG1vZHVsZU5hbWUpO1xuICAgIGNvbnN0IGNvbmZpZyA9IHNldERlZmF1bHRzKHNjaGVtYSwgaW5wdXRDb25maWcpO1xuICAgIHJ1bkFsbFZhbGlkYXRvcnNJbkNvbmZpZ1RyZWUoc2NoZW1hLCBjb25maWcsIG1vZHVsZU5hbWUpO1xuICAgIGRlbGV0ZSBjb25maWcuZXh0ZW5zaW9uU2xvdHM7XG4gICAgcmV0dXJuIGNvbmZpZztcbn1cbmZ1bmN0aW9uIGdldENvbmZpZ0Zvck1vZHVsZUltcGxpY2l0U2NoZW1hKG1vZHVsZU5hbWUsIGNvbmZpZ1N0YXRlLCB0ZW1wQ29uZmlnU3RhdGUpIHtcbiAgICBjb25zdCBpbnB1dENvbmZpZyA9IG1lcmdlQ29uZmlnc0Zvcihtb2R1bGVOYW1lLCBnZXRQcm92aWRlZENvbmZpZ3MoY29uZmlnU3RhdGUsIHRlbXBDb25maWdTdGF0ZSkpO1xuICAgIGNvbnN0IGNvbmZpZyA9IHNldERlZmF1bHRzKGltcGxpY2l0Q29uZmlnU2NoZW1hLCBpbnB1dENvbmZpZyk7XG4gICAgcnVuQWxsVmFsaWRhdG9yc0luQ29uZmlnVHJlZShpbXBsaWNpdENvbmZpZ1NjaGVtYSwgY29uZmlnLCBtb2R1bGVOYW1lKTtcbiAgICBkZWxldGUgY29uZmlnLmV4dGVuc2lvblNsb3RzO1xuICAgIHJldHVybiBjb25maWc7XG59XG5mdW5jdGlvbiBtZXJnZUNvbmZpZ3NGb3IobW9kdWxlTmFtZSwgYWxsQ29uZmlncykge1xuICAgIGNvbnN0IGFsbENvbmZpZ3NGb3JNb2R1bGUgPSBhbGxDb25maWdzLm1hcCgoeyBbbW9kdWxlTmFtZV06IGMgfSk9PmMpLmZpbHRlcigoYyk9PiEhYyk7XG4gICAgcmV0dXJuIG1lcmdlQ29uZmlncyhhbGxDb25maWdzRm9yTW9kdWxlKTtcbn1cbmZ1bmN0aW9uIG1lcmdlQ29uZmlncyhjb25maWdzKSB7XG4gICAgY29uc3QgbWVyZ2VEZWVwQWxsID0gcmVkdWNlKG1lcmdlRGVlcFJpZ2h0KTtcbiAgICByZXR1cm4gbWVyZ2VEZWVwQWxsKHt9LCBjb25maWdzKTtcbn1cbi8qKlxuICogUmVjdXJzaXZlbHkgY2hlY2sgdGhlIHByb3ZpZGVkIGNvbmZpZyB0cmVlIHRvIG1ha2Ugc3VyZSB0aGF0IGFsbFxuICogb2YgdGhlIHByb3ZpZGVkIHByb3BlcnRpZXMgZXhpc3QgaW4gdGhlIHNjaGVtYSwgYW5kIHRoYXQgdHlwZXMgYXJlXG4gKiBjb3JyZWN0LiBEb2VzIG5vdCBydW4gdmFsaWRhdG9ycyB5ZXQsIHNpbmNlIHRob3NlIHdpbGwgYmUgcnVuIG9uXG4gKiB0aGUgY29uZmlnIHdpdGggdGhlIGRlZmF1bHRzIGZpbGxlZCBpbi5cbiAqLyBmdW5jdGlvbiB2YWxpZGF0ZVN0cnVjdHVyZShzY2hlbWEsIGNvbmZpZywga2V5UGF0aCA9ICcnKSB7XG4gICAgLy8gdmFsaWRhdGUgZWFjaCBjb25zdGl0dWVudCBlbGVtZW50XG4gICAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXMoY29uZmlnKSl7XG4gICAgICAgIGNvbnN0IHZhbHVlID0gY29uZmlnW2tleV07XG4gICAgICAgIGNvbnN0IHRoaXNLZXlQYXRoID0ga2V5UGF0aCArICcuJyArIGtleTtcbiAgICAgICAgY29uc3Qgc2NoZW1hUGFydCA9IHNjaGVtYVtrZXldO1xuICAgICAgICBpZiAoIXNjaGVtYS5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG4gICAgICAgICAgICBpZiAoIShrZXkgPT09ICdleHRlbnNpb25TbG90cycgJiYga2V5UGF0aCAhPT0gJycpKSB7XG4gICAgICAgICAgICAgICAgbG9nRXJyb3IodGhpc0tleVBhdGgsIGBVbmtub3duIGNvbmZpZyBrZXkgJyR7dGhpc0tleVBhdGh9JyBwcm92aWRlZC4gSWdub3JpbmcuYCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICB2YWxpZGF0ZUJyYW5jaFN0cnVjdHVyZShzY2hlbWFQYXJ0LCB2YWx1ZSwgdGhpc0tleVBhdGgpO1xuICAgIH1cbn1cbmZ1bmN0aW9uIHZhbGlkYXRlQnJhbmNoU3RydWN0dXJlKHNjaGVtYVBhcnQsIHZhbHVlLCBrZXlQYXRoKSB7XG4gICAgY2hlY2tUeXBlKGtleVBhdGgsIHNjaGVtYVBhcnQuX3R5cGUsIHZhbHVlKTtcbiAgICBpZiAoaXNPcmRpbmFyeU9iamVjdCh2YWx1ZSkpIHtcbiAgICAgICAgaWYgKHNjaGVtYVBhcnQuX3R5cGUgPT09IFR5cGUuT2JqZWN0KSB7XG4gICAgICAgICAgICAvLyB2YWxpZGF0ZSBhcyBmcmVlZm9ybSBvYmplY3RcbiAgICAgICAgICAgIHZhbGlkYXRlRnJlZWZvcm1PYmplY3RTdHJ1Y3R1cmUoc2NoZW1hUGFydCwgdmFsdWUsIGtleVBhdGgpO1xuICAgICAgICB9IGVsc2UgaWYgKCEoc2NoZW1hUGFydC5oYXNPd25Qcm9wZXJ0eSgnX2RlZmF1bHQnKSB8fCBzY2hlbWFQYXJ0Lmhhc093blByb3BlcnR5KCdfdHlwZScpKSkge1xuICAgICAgICAgICAgLy8gdmFsaWRhdGUgYXMgbm9ybWFsIG5lc3RlZCBjb25maWdcbiAgICAgICAgICAgIHZhbGlkYXRlU3RydWN0dXJlKHNjaGVtYVBhcnQsIHZhbHVlLCBrZXlQYXRoKTtcbiAgICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChzY2hlbWFQYXJ0Ll90eXBlID09PSBUeXBlLkFycmF5KSB7XG4gICAgICAgICAgICB2YWxpZGF0ZUFycmF5U3RydWN0dXJlKHNjaGVtYVBhcnQsIHZhbHVlLCBrZXlQYXRoKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbmZ1bmN0aW9uIHZhbGlkYXRlRnJlZWZvcm1PYmplY3RTdHJ1Y3R1cmUoZnJlZWZvcm1PYmplY3RTY2hlbWEsIGNvbmZpZywga2V5UGF0aCkge1xuICAgIGlmIChmcmVlZm9ybU9iamVjdFNjaGVtYS5fZWxlbWVudHMpIHtcbiAgICAgICAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXMoY29uZmlnKSl7XG4gICAgICAgICAgICBjb25zdCB2YWx1ZSA9IGNvbmZpZ1trZXldO1xuICAgICAgICAgICAgdmFsaWRhdGVCcmFuY2hTdHJ1Y3R1cmUoZnJlZWZvcm1PYmplY3RTY2hlbWEuX2VsZW1lbnRzLCB2YWx1ZSwgYCR7a2V5UGF0aH0uJHtrZXl9YCk7XG4gICAgICAgIH1cbiAgICB9XG59XG5mdW5jdGlvbiB2YWxpZGF0ZUFycmF5U3RydWN0dXJlKGFycmF5U2NoZW1hLCB2YWx1ZSwga2V5UGF0aCkge1xuICAgIGNvbnN0IHZhbGlkYXRlZEFzQXJyYXkgPSBjaGVja1R5cGUoa2V5UGF0aCwgVHlwZS5BcnJheSwgdmFsdWUpO1xuICAgIGlmICghdmFsaWRhdGVkQXNBcnJheSkge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIC8vIGlmIHRoZXJlIGlzIGFuIGFycmF5IGVsZW1lbnQgb2JqZWN0IHNjaGVtYSwgdmVyaWZ5IHRoYXQgZWxlbWVudHMgbWF0Y2ggaXRcbiAgICBpZiAoaGFzT2JqZWN0U2NoZW1hKGFycmF5U2NoZW1hLl9lbGVtZW50cykpIHtcbiAgICAgICAgZm9yKGxldCBpID0gMDsgaSA8IHZhbHVlLmxlbmd0aDsgaSsrKXtcbiAgICAgICAgICAgIHZhbGlkYXRlQnJhbmNoU3RydWN0dXJlKGFycmF5U2NoZW1hLl9lbGVtZW50cywgdmFsdWVbaV0sIGAke2tleVBhdGh9WyR7aX1dYCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZm9yKGxldCBpID0gMDsgaSA8IHZhbHVlLmxlbmd0aDsgaSsrKXtcbiAgICAgICAgY2hlY2tUeXBlKGAke2tleVBhdGh9WyR7aX1dYCwgYXJyYXlTY2hlbWEuX2VsZW1lbnRzPy5fdHlwZSwgdmFsdWVbaV0pO1xuICAgIH1cbn1cbi8qKlxuICogUnVuIGFsbCB0aGUgdmFsaWRhdG9ycyBpbiB0aGUgY29uZmlnIHRyZWUuIFRoaXMgc2hvdWxkIGJlIHJ1blxuICogb24gdGhlIGNvbmZpZyBvYmplY3QgYWZ0ZXIgaXQgaGFzIGJlZW4gZmlsbGVkIGluIHdpdGggYWxsIHRoZSBkZWZhdWx0cywgc2luY2VcbiAqIGhpZ2hlci1sZXZlbCB2YWxpZGF0b3JzIG1heSByZWZlciB0byBkZWZhdWx0IHZhbHVlcy5cbiAqLyBmdW5jdGlvbiBydW5BbGxWYWxpZGF0b3JzSW5Db25maWdUcmVlKHNjaGVtYSwgY29uZmlnLCBrZXlQYXRoID0gJycpIHtcbiAgICAvLyBJZiBgIXNjaGVtYWAsIHRoZXJlIHNob3VsZCBoYXZlIGJlZW4gYSBzdHJ1Y3R1cmFsIHZhbGlkYXRpb24gZXJyb3IgcHJpbnRlZCBhbHJlYWR5LlxuICAgIGlmIChzY2hlbWEpIHtcbiAgICAgICAgaWYgKGNvbmZpZyAhPT0gc2NoZW1hLl9kZWZhdWx0KSB7XG4gICAgICAgICAgICBydW5WYWxpZGF0b3JzKGtleVBhdGgsIHNjaGVtYS5fdmFsaWRhdG9ycywgY29uZmlnKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaXNPcmRpbmFyeU9iamVjdChjb25maWcpKSB7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyhjb25maWcpKXtcbiAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZSA9IGNvbmZpZ1trZXldO1xuICAgICAgICAgICAgICAgIGNvbnN0IHRoaXNLZXlQYXRoID0ga2V5UGF0aCArICcuJyArIGtleTtcbiAgICAgICAgICAgICAgICBjb25zdCBzY2hlbWFQYXJ0ID0gc2NoZW1hW2tleV07XG4gICAgICAgICAgICAgICAgaWYgKHNjaGVtYS5fdHlwZSA9PT0gVHlwZS5PYmplY3QgJiYgc2NoZW1hLl9lbGVtZW50cykge1xuICAgICAgICAgICAgICAgICAgICBydW5BbGxWYWxpZGF0b3JzSW5Db25maWdUcmVlKHNjaGVtYS5fZWxlbWVudHMsIHZhbHVlLCB0aGlzS2V5UGF0aCk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcnVuQWxsVmFsaWRhdG9yc0luQ29uZmlnVHJlZShzY2hlbWFQYXJ0LCB2YWx1ZSwgdGhpc0tleVBhdGgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmIChBcnJheS5pc0FycmF5KGNvbmZpZykgJiYgc2NoZW1hLl9lbGVtZW50cykge1xuICAgICAgICAgICAgZm9yKGxldCBpID0gMDsgaSA8IGNvbmZpZy5sZW5ndGg7IGkrKyl7XG4gICAgICAgICAgICAgICAgcnVuQWxsVmFsaWRhdG9yc0luQ29uZmlnVHJlZShzY2hlbWEuX2VsZW1lbnRzLCBjb25maWdbaV0sIGAke2tleVBhdGh9WyR7aX1dYCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG59XG4vKipcbiAqIFJ1biB0eXBlIHZhbGlkYXRpb24gZm9yIHRoZSB2YWx1ZSwgbG9nZ2luZyBhbnkgZXJyb3JzLlxuICogQHJldHVybnMgdHJ1ZSBpZiB2YWxpZGF0aW9uIHBhc3NlcywgZmFsc2Ugb3RoZXJ3aXNlXG4gKi8gZnVuY3Rpb24gY2hlY2tUeXBlKGtleVBhdGgsIF90eXBlLCB2YWx1ZSkge1xuICAgIGlmIChfdHlwZSkge1xuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVuc2FmZS1mdW5jdGlvbi10eXBlXG4gICAgICAgIGNvbnN0IHZhbGlkYXRvciA9IHtcbiAgICAgICAgICAgIEFycmF5OiBpc0FycmF5LFxuICAgICAgICAgICAgQm9vbGVhbjogaXNCb29sZWFuLFxuICAgICAgICAgICAgQ29uY2VwdFV1aWQ6IGlzVXVpZCxcbiAgICAgICAgICAgIE51bWJlcjogaXNOdW1iZXIsXG4gICAgICAgICAgICBPYmplY3Q6IGlzT2JqZWN0LFxuICAgICAgICAgICAgU3RyaW5nOiBpc1N0cmluZyxcbiAgICAgICAgICAgIFVVSUQ6IGlzVXVpZCxcbiAgICAgICAgICAgIFBlcnNvbkF0dHJpYnV0ZVR5cGVVdWlkOiBpc1V1aWQsXG4gICAgICAgICAgICBQYXRpZW50SWRlbnRpZmllclR5cGVVdWlkOiBpc1V1aWRcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIHJ1blZhbGlkYXRvcnMoa2V5UGF0aCwgW1xuICAgICAgICAgICAgdmFsaWRhdG9yW190eXBlXVxuICAgICAgICBdLCB2YWx1ZSk7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xufVxuLyoqXG4gKiBSdW5zIHZhbGlkYXRvcnMsIGxvZ2dpbmcgZXJyb3JzLlxuICogQHJldHVybnMgdHJ1ZSBpZiBhbGwgcGFzcywgZmFsc2Ugb3RoZXJ3aXNlLlxuICovIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW5zYWZlLWZ1bmN0aW9uLXR5cGVcbmZ1bmN0aW9uIHJ1blZhbGlkYXRvcnMoa2V5UGF0aCwgdmFsaWRhdG9ycywgdmFsdWUpIHtcbiAgICBsZXQgcmV0dXJuVmFsdWUgPSB0cnVlO1xuICAgIGlmICh2YWxpZGF0b3JzKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBmb3IgKGxldCB2YWxpZGF0b3Igb2YgdmFsaWRhdG9ycyl7XG4gICAgICAgICAgICAgICAgY29uc3QgdmFsaWRhdG9yUmVzdWx0ID0gdmFsaWRhdG9yKHZhbHVlKTtcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHZhbGlkYXRvclJlc3VsdCA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbWVzc2FnZSA9IHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgPyBgSW52YWxpZCBjb25maWd1cmF0aW9uIGZvciAke2tleVBhdGh9OiAke3ZhbGlkYXRvclJlc3VsdH1gIDogYEludmFsaWQgY29uZmlndXJhdGlvbiB2YWx1ZSAke3ZhbHVlfSBmb3IgJHtrZXlQYXRofTogJHt2YWxpZGF0b3JSZXN1bHR9YDtcbiAgICAgICAgICAgICAgICAgICAgbG9nRXJyb3Ioa2V5UGF0aCwgbWVzc2FnZSk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVyblZhbHVlID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKGBTa2lwcGluZyBpbnZhbGlkIHZhbGlkYXRvciBhdCBcIiR7a2V5UGF0aH1cIi4gRW5jb3VudGVyZWQgZXJyb3JcXG5cXHQke2V9YCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJldHVyblZhbHVlO1xufVxuLy8gUmVjdXJzaXZlbHkgZmlsbCBpbiB0aGUgY29uZmlnIHdpdGggdmFsdWVzIGZyb20gdGhlIHNjaGVtYS5cbmNvbnN0IHNldERlZmF1bHRzID0gKHNjaGVtYSwgaW5wdXRDb25maWcpPT57XG4gICAgY29uc3QgY29uZmlnID0gY2xvbmUoaW5wdXRDb25maWcpO1xuICAgIGlmICghc2NoZW1hKSB7XG4gICAgICAgIHJldHVybiBjb25maWc7XG4gICAgfVxuICAgIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKHNjaGVtYSkpe1xuICAgICAgICBjb25zdCBjb25maWdQYXJ0ID0gY29uZmlnW2tleV07XG4gICAgICAgIGNvbnN0IHNjaGVtYVBhcnQgPSBzY2hlbWFba2V5XTtcbiAgICAgICAgLy8gVGhlIGBzY2hlbWFQYXJ0ICYmYCBjbGF1c2Ugb2YgdGhpcyBgaWZgIHN0YXRlbWVudCB3aWxsIG9ubHkgZmFpbFxuICAgICAgICAvLyBpZiB0aGUgc2NoZW1hIGlzIHZlcnkgaW52YWxpZC4gSXQgaXMgdGhlcmUgdG8gcHJldmVudCB0aGUgYXBwIGZyb21cbiAgICAgICAgLy8gY3Jhc2hpbmcgY29tcGxldGVseSwgdGhvdWdoIGl0IHdpbGwgcHJvZHVjZSB1bmV4cGVjdGVkIGJlaGF2aW9yLlxuICAgICAgICAvLyBJZiB0aGlzIGhhcHBlbnMsIHRoZXJlIHNob3VsZCBiZSBsZWdpYmxlIGVycm9ycyBpbiB0aGUgY29uc29sZSBmcm9tXG4gICAgICAgIC8vIHRoZSBzY2hlbWEgdmFsaWRhdG9yLlxuICAgICAgICBpZiAoc2NoZW1hUGFydCAmJiAoc2NoZW1hUGFydC5oYXNPd25Qcm9wZXJ0eSgnX3R5cGUnKSB8fCBzY2hlbWFQYXJ0Lmhhc093blByb3BlcnR5KCdfZGVmYXVsdCcpKSkge1xuICAgICAgICAgICAgLy8gV2UgYXNzdW1lIHRoYXQgc2NoZW1hUGFydCBkZWZpbmVzIGEgY29uZmlnIHZhbHVlLCBzaW5jZSBpdCBoYXNcbiAgICAgICAgICAgIC8vIGEgcHJvcGVydHkgYF90eXBlYCBvciBgX2RlZmF1bHRgLlxuICAgICAgICAgICAgaWYgKCFjb25maWcuaGFzT3duUHJvcGVydHkoa2V5KSkge1xuICAgICAgICAgICAgICAgIGNvbmZpZ1trZXldID0gc2NoZW1hUGFydFsnX2RlZmF1bHQnXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIFdlIGFsc28gY2hlY2sgaWYgaXQgaXMgYW4gb2JqZWN0IG9yIGFycmF5IHdpdGggb2JqZWN0IGVsZW1lbnRzLCBpbiB3aGljaCBjYXNlIHdlIHJlY3Vyc2VcbiAgICAgICAgICAgIGNvbnN0IGVsZW1lbnRzID0gc2NoZW1hUGFydC5fZWxlbWVudHM7XG4gICAgICAgICAgICBpZiAoY29uZmlnUGFydCAmJiBoYXNPYmplY3RTY2hlbWEoZWxlbWVudHMpKSB7XG4gICAgICAgICAgICAgICAgaWYgKHNjaGVtYVBhcnQuX3R5cGUgPT09IFR5cGUuQXJyYXkgJiYgQXJyYXkuaXNBcnJheShjb25maWdQYXJ0KSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBjb25maWdXaXRoRGVmYXVsdHMgPSBjb25maWdQYXJ0Lm1hcCgoY29uZik9PnNldERlZmF1bHRzKGVsZW1lbnRzLCBjb25mKSk7XG4gICAgICAgICAgICAgICAgICAgIGNvbmZpZ1trZXldID0gY29uZmlnV2l0aERlZmF1bHRzO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoc2NoZW1hUGFydC5fdHlwZSA9PT0gVHlwZS5PYmplY3QpIHtcbiAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgb2JqZWN0S2V5IG9mIE9iamVjdC5rZXlzKGNvbmZpZ1BhcnQpKXtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbmZpZ1BhcnRbb2JqZWN0S2V5XSA9IHNldERlZmF1bHRzKGVsZW1lbnRzLCBjb25maWdQYXJ0W29iamVjdEtleV0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKGlzT3JkaW5hcnlPYmplY3Qoc2NoZW1hUGFydCkpIHtcbiAgICAgICAgICAgIC8vIFNpbmNlIHNjaGVtYVBhcnQgaGFzIG5vIHByb3BlcnR5IFwiX3R5cGVcIiwgaWYgaXQncyBhbiBvcmRpbmFyeSBvYmplY3RcbiAgICAgICAgICAgIC8vICh1bmxpa2UsIGltcG9ydGFudGx5LCB0aGUgdmFsaWRhdG9ycyBhcnJheSksIHdlIGFzc3VtZSBpdCBpcyBhIHBhcmVudCBjb25maWcgcHJvcGVydHkuXG4gICAgICAgICAgICAvLyBXZSByZWN1cnNlIHRvIGNvbmZpZ1trZXldIGFuZCBzY2hlbWFba2V5XS4gRGVmYXVsdCBjb25maWdba2V5XSB0byB7fS5cbiAgICAgICAgICAgIGNvbnN0IHNlbGVjdGVkQ29uZmlnUGFydCA9IGNvbmZpZ1BhcnQgPz8ge307XG4gICAgICAgICAgICAvLyBUaGVyZSB3aWxsIGhhdmUgYmVlbiBhIHZhbGlkYXRpb24gZXJyb3IgYWxyZWFkeSBpZiBjb25maWdQYXJ0IGlzIG5vdCBhIHBsYWluIG9iamVjdC5cbiAgICAgICAgICAgIGlmIChpc09yZGluYXJ5T2JqZWN0KHNlbGVjdGVkQ29uZmlnUGFydCkpIHtcbiAgICAgICAgICAgICAgICBjb25maWdba2V5XSA9IHNldERlZmF1bHRzKHNjaGVtYVBhcnQsIHNlbGVjdGVkQ29uZmlnUGFydCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGNvbmZpZztcbn07XG5mdW5jdGlvbiBoYXNPYmplY3RTY2hlbWEoZWxlbWVudHNTY2hlbWEpIHtcbiAgICByZXR1cm4gISFlbGVtZW50c1NjaGVtYSAmJiBPYmplY3Qua2V5cyhlbGVtZW50c1NjaGVtYSkuZmlsdGVyKChlKT0+IVtcbiAgICAgICAgICAgICdfZGVmYXVsdCcsXG4gICAgICAgICAgICAnX3ZhbGlkYXRvcnMnXG4gICAgICAgIF0uaW5jbHVkZXMoZSkpLmxlbmd0aCA+IDA7XG59XG5mdW5jdGlvbiBpc09yZGluYXJ5T2JqZWN0KHZhbHVlKSB7XG4gICAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiYgIUFycmF5LmlzQXJyYXkodmFsdWUpICYmIHZhbHVlICE9PSBudWxsO1xufVxuLyoqIEtlZXAgdHJhY2sgb2Ygd2hpY2ggdmFsaWRhdGlvbiBlcnJvcnMgd2UgaGF2ZSBkaXNwbGF5ZWQuIEVhY2ggb25lIHNob3VsZCBvbmx5IGJlIGRpc3BsYXllZCBvbmNlLiAqLyBsZXQgZGlzcGxheWVkVmFsaWRhdGlvbk1lc3NhZ2VzID0gbmV3IFNldCgpO1xuZnVuY3Rpb24gbG9nRXJyb3Ioa2V5UGF0aCwgbWVzc2FnZSkge1xuICAgIGNvbnN0IGtleSA9IGAke2tleVBhdGh9Ojo6JHttZXNzYWdlfWA7XG4gICAgLy8gdGVjaG5pY2FsbHksIHRoaXMgc2hvdWxkIG5vdCBiZSBwb3NzaWJsZSwgYnV0IGJlY2F1c2Ugb2YgaG93IHRoaW5ncyB3aW5kLXVwIHRyYW5zcGlsZWQsIHRoaXMgaXNuJ3QgaW1wb3NzaWJsZVxuICAgIGlmICghZGlzcGxheWVkVmFsaWRhdGlvbk1lc3NhZ2VzKSB7XG4gICAgICAgIGRpc3BsYXllZFZhbGlkYXRpb25NZXNzYWdlcyA9IG5ldyBTZXQoKTtcbiAgICB9XG4gICAgaWYgKCFkaXNwbGF5ZWRWYWxpZGF0aW9uTWVzc2FnZXMuaGFzKGtleSkpIHtcbiAgICAgICAgY29uc29sZS5lcnJvcihtZXNzYWdlKTtcbiAgICAgICAgZGlzcGxheWVkVmFsaWRhdGlvbk1lc3NhZ2VzLmFkZChrZXkpO1xuICAgIH1cbn1cbi8qKlxuICogTm9ybWFsbHksIGNvbmZpZ3VyYXRpb24gZXJyb3JzIGFyZSBvbmx5IGRpc3BsYXllZCBvbmNlLiBUaGlzIGZ1bmN0aW9uIGNsZWFycyB0aGUgbGlzdCBvZlxuICogZGlzcGxheWVkIGVycm9ycywgc28gdGhhdCB0aGV5IHdpbGwgYmUgZGlzcGxheWVkIGFnYWluLlxuICpcbiAqIEBpbnRlcm5hbFxuICovIGV4cG9ydCBmdW5jdGlvbiBjbGVhckNvbmZpZ0Vycm9ycyhrZXlQYXRoKSB7XG4gICAgaWYgKGtleVBhdGgpIHtcbiAgICAgICAgZGlzcGxheWVkVmFsaWRhdGlvbk1lc3NhZ2VzLmZvckVhY2goKGtleSk9PntcbiAgICAgICAgICAgIGlmIChrZXkuc3RhcnRzV2l0aChrZXlQYXRoKSkge1xuICAgICAgICAgICAgICAgIGRpc3BsYXllZFZhbGlkYXRpb25NZXNzYWdlcy5kZWxldGUoa2V5KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgZGlzcGxheWVkVmFsaWRhdGlvbk1lc3NhZ2VzLmNsZWFyKCk7XG4gICAgfVxufVxuLyoqXG4gKiBDbGVhbnMgdXAgYWxsIGNvbmZpZyBzdG9yZSBzdWJzY3JpcHRpb25zIGFuZCByZS1lc3RhYmxpc2hlcyB0aGVtLiBUaGlzIGlzIHByaW1hcmlseVxuICogdXNlZnVsIGZvciB0ZXN0aW5nLCB3aGVyZSBzdWJzY3JpcHRpb25zIHNldCB1cCBhdCBtb2R1bGUgbG9hZCB0aW1lIG5lZWQgdG8gYmUgY2xlYXJlZFxuICogYmV0d2VlbiB0ZXN0cyB0byBwcmV2ZW50IGluZmluaXRlIHVwZGF0ZSBsb29wcy4gQWZ0ZXIgY2xlYXJpbmcsIHN1YnNjcmlwdGlvbnMgYXJlXG4gKiByZS1lc3RhYmxpc2hlZCBzbyB0aGUgY29uZmlnIHN5c3RlbSBjb250aW51ZXMgdG8gd29yayBub3JtYWxseS5cbiAqXG4gKiBAaW50ZXJuYWxcbiAqLyBleHBvcnQgZnVuY3Rpb24gcmVzZXRDb25maWdTeXN0ZW0oKSB7XG4gICAgY29uZmlnU3Vic2NyaXB0aW9ucy5mb3JFYWNoKCh1bnN1YnNjcmliZSk9PnVuc3Vic2NyaWJlKCkpO1xuICAgIGNvbmZpZ1N1YnNjcmlwdGlvbnMubGVuZ3RoID0gMDtcbiAgICBzZXR1cENvbmZpZ1N1YnNjcmlwdGlvbnMoKTtcbn1cbi8qKlxuICogQ29waWVkIG92ZXIgZnJvbSBlc20tZXh0ZW5zaW9ucy4gSXQgcmlnaHRseSBiZWxvbmdzIHRvIHRoYXQgbW9kdWxlLCBidXQgZXNtLWNvbmZpZ1xuICogY2Fubm90IGRlcGVuZCBvbiBlc20tZXh0ZW5zaW9ucy5cbiAqLyBmdW5jdGlvbiBnZXRFeHRlbnNpb25OYW1lRnJvbUlkKGV4dGVuc2lvbklkKSB7XG4gICAgY29uc3QgW2V4dGVuc2lvbk5hbWVdID0gZXh0ZW5zaW9uSWQuc3BsaXQoJyMnKTtcbiAgICByZXR1cm4gZXh0ZW5zaW9uTmFtZTtcbn1cbi8qKlxuICogVGhlIHRyYW5zbGF0aW9uIG92ZXJyaWRlcyBzY2hlbWEgaXMgdXNlZCBpbiB0aGUgaW1wbGljaXQgc2NoZW1hIGdpdmVuIHRvIGV2ZXJ5IG1vZHVsZTtcbiAqIHBsdXMgYW55IGFkZGl0aW9uYWwgdHJhbnNsYXRpb24gbmFtZXNwYWNlcyAoYXQgdGltZSBvZiB3cml0aW5nLCB0aGlzIGlzIGp1c3QgJ2NvcmUnKS5cbiAqLyBjb25zdCB0cmFuc2xhdGlvbk92ZXJyaWRlc1NjaGVtYSA9IHtcbiAgICAnVHJhbnNsYXRpb24gb3ZlcnJpZGVzJzoge1xuICAgICAgICBfZGVzY3JpcHRpb246ICdQZXItbGFuZ3VhZ2Ugb3ZlcnJpZGVzIGZvciBmcm9udGVuZCB0cmFuc2xhdGlvbnMgc2hvdWxkIGJlIGtleWVkIGJ5IGxhbmd1YWdlIGNvZGUgYW5kIGVhY2ggbGFuZ3VhZ2UgZGljdGlvbmFyeSBjb250YWlucyB0aGUgdHJhbnNsYXRpb24ga2V5IGFuZCB0aGUgZGlzcGxheSB2YWx1ZScsXG4gICAgICAgIF90eXBlOiBUeXBlLk9iamVjdCxcbiAgICAgICAgX2RlZmF1bHQ6IHt9LFxuICAgICAgICBfdmFsaWRhdG9yczogW1xuICAgICAgICAgICAgdmFsaWRhdG9yKChvKT0+T2JqZWN0LmtleXMobykuZXZlcnkoKGspPT4vXlthLXpdezIsM30oLVtBLVpdezIsM30pPyQvLnRlc3QoaykpLCAobyk9PntcbiAgICAgICAgICAgICAgICBjb25zdCBiYWRLZXlzID0gT2JqZWN0LmtleXMobykuZmlsdGVyKChrKT0+IS9eW2Etel17MiwzfSgtW0EtWl17MiwzfSk/JC8udGVzdChrKSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBUaGUgJ1RyYW5zbGF0aW9uIG92ZXJyaWRlcycgb2JqZWN0IHNob3VsZCBoYXZlIGxhbmd1YWdlIGNvZGVzIGZvciBrZXlzLiBMYW5ndWFnZSBjb2RlcyBtdXN0IGJlIGluIHRoZSBmb3JtIG9mIGEgdHdvLXRvLXRocmVlIGxldHRlciBsYW5ndWFnZSBjb2RlIG9wdGlvbmFsbHkgZm9sbG93ZWQgYnkgYSBoeXBoZW4gYW5kIGEgdHdvLXRvLXRocmVlIGxldHRlciBjb3VudHJ5IGNvZGUuIFRoZSBmb2xsb3dpbmcga2V5cyBkbyBub3QgY29uZm9ybTogJHtiYWRLZXlzLmpvaW4oJywgJyl9LmA7XG4gICAgICAgICAgICB9KVxuICAgICAgICBdXG4gICAgfVxufTtcbi8qKlxuICogVGhlIGltcGxpY2l0Q29uZmlnU2NoZW1hIGlzIGltcGxpY2l0bHkgaW5jbHVkZWQgaW4gZXZlcnkgY29uZmlndXJhdGlvbiBzY2hlbWFcbiAqLyBjb25zdCBpbXBsaWNpdENvbmZpZ1NjaGVtYSA9IHtcbiAgICAnRGlzcGxheSBjb25kaXRpb25zJzoge1xuICAgICAgICBwcml2aWxlZ2VzOiB7XG4gICAgICAgICAgICBfZGVzY3JpcHRpb246ICdUaGUgcHJpdmlsZWdlKHMpIHRoZSB1c2VyIG11c3QgaGF2ZSB0byB1c2UgdGhpcyBleHRlbnNpb24nLFxuICAgICAgICAgICAgX3R5cGU6IFR5cGUuQXJyYXksXG4gICAgICAgICAgICBfZGVmYXVsdDogW11cbiAgICAgICAgfSxcbiAgICAgICAgZXhwcmVzc2lvbjoge1xuICAgICAgICAgICAgX2Rlc2NyaXB0aW9uOiAnVGhlIGV4cHJlc3Npb24gdGhhdCBkZXRlcm1pbmVzIHdoZXRoZXIgdGhlIGV4dGVuc2lvbiBpcyBkaXNwbGF5ZWQnLFxuICAgICAgICAgICAgX3R5cGU6IFR5cGUuU3RyaW5nLFxuICAgICAgICAgICAgX2RlZmF1bHQ6IHVuZGVmaW5lZFxuICAgICAgICB9XG4gICAgfSxcbiAgICAuLi50cmFuc2xhdGlvbk92ZXJyaWRlc1NjaGVtYVxufTtcbiJdLCJuYW1lcyI6WyJjbG9uZSIsImVxdWFscyIsInJlZHVjZSIsIm1lcmdlRGVlcFJpZ2h0Iiwib21pdCIsIlR5cGUiLCJpc0FycmF5IiwiaXNCb29sZWFuIiwiaXNVdWlkIiwiaXNOdW1iZXIiLCJpc09iamVjdCIsImlzU3RyaW5nIiwidmFsaWRhdG9yIiwiY29uZmlnRXh0ZW5zaW9uU3RvcmUiLCJjb25maWdJbnRlcm5hbFN0b3JlIiwiZ2V0Q29uZmlnU3RvcmUiLCJnZXRFeHRlbnNpb25Db25maWciLCJnZXRFeHRlbnNpb25TbG90c0NvbmZpZ1N0b3JlIiwiZ2V0RXh0ZW5zaW9uc0NvbmZpZ1N0b3JlIiwiaW1wbGVtZW50ZXJUb29sc0NvbmZpZ1N0b3JlIiwidGVtcG9yYXJ5Q29uZmlnU3RvcmUiLCJjb25maWdTdWJzY3JpcHRpb25zIiwicmVjb21wdXRlQWxsQ29uZmlncyIsImNvbmZpZ1N0YXRlIiwiZ2V0U3RhdGUiLCJ0ZW1wQ29uZmlnU3RhdGUiLCJleHRlbnNpb25TdGF0ZSIsImNvbXB1dGVNb2R1bGVDb25maWciLCJjb21wdXRlSW1wbGVtZW50ZXJUb29sc0NvbmZpZyIsImNvbXB1dGVFeHRlbnNpb25TbG90Q29uZmlncyIsImNvbXB1dGVFeHRlbnNpb25Db25maWdzIiwic2V0dXBDb25maWdTdWJzY3JpcHRpb25zIiwicHVzaCIsInN1YnNjcmliZSIsInN0YXRlIiwidGVtcFN0YXRlIiwibW9kdWxlTmFtZSIsIk9iamVjdCIsImtleXMiLCJzY2hlbWFzIiwibW9kdWxlU3RvcmUiLCJuZXdTdGF0ZSIsIm1vZHVsZUxvYWRlZCIsImNvbmZpZyIsImdldENvbmZpZ0Zvck1vZHVsZSIsInRyYW5zbGF0aW9uT3ZlcnJpZGVzTG9hZGVkIiwibG9hZGVkIiwiZ2V0Q29uZmlnRm9yTW9kdWxlSW1wbGljaXRTY2hlbWEiLCJzZXRTdGF0ZSIsInNsb3RDb25maWdzIiwiZ2V0RXh0ZW5zaW9uU2xvdENvbmZpZ3MiLCJuZXdTbG90U3RvcmVFbnRyaWVzIiwiZnJvbUVudHJpZXMiLCJlbnRyaWVzIiwibWFwIiwic2xvdE5hbWUiLCJzbG90U3RvcmUiLCJvbGRTdGF0ZSIsInNsb3RzIiwiZ2V0SW1wbGVtZW50ZXJUb29sc0NvbmZpZyIsImNvbmZpZ3MiLCJleHRlbnNpb24iLCJtb3VudGVkRXh0ZW5zaW9ucyIsImNvbXB1dGVFeHRlbnNpb25Db25maWciLCJzbG90TW9kdWxlTmFtZSIsImV4dGVuc2lvbk1vZHVsZU5hbWUiLCJleHRlbnNpb25JZCIsImV4dGVuc2lvbnNDb25maWdTdG9yZSIsImRlZmluZUNvbmZpZ1NjaGVtYSIsInNjaGVtYSIsInZhbGlkYXRlQ29uZmlnU2NoZW1hIiwiZW5oYW5jZWRTY2hlbWEiLCJpbXBsaWNpdENvbmZpZ1NjaGVtYSIsInJlZ2lzdGVyTW9kdWxlV2l0aENvbmZpZ1N5c3RlbSIsInJlZ2lzdGVyTW9kdWxlTG9hZCIsInJlZ2lzdGVyVHJhbnNsYXRpb25OYW1lc3BhY2UiLCJuYW1lc3BhY2UiLCJ0cmFuc2xhdGlvbk92ZXJyaWRlc1NjaGVtYSIsImRlZmluZUV4dGVuc2lvbkNvbmZpZ1NjaGVtYSIsImV4dGVuc2lvbk5hbWUiLCJjb25zb2xlIiwiZXJyb3IiLCJwcm92aWRlIiwic291cmNlTmFtZSIsInByb3ZpZGVkQ29uZmlncyIsInNvdXJjZSIsImdldENvbmZpZyIsIlByb21pc2UiLCJyZXNvbHZlIiwic3RvcmUiLCJ1cGRhdGUiLCJ1bnN1YnNjcmliZSIsImdldFRyYW5zbGF0aW9uT3ZlcnJpZGVzIiwicHJvbWlzZXMiLCJjb25maWdTdG9yZSIsInRyYW5zbGF0aW9uT3ZlcnJpZGVzIiwiYWxsIiwicHJvY2Vzc0NvbmZpZyIsInByb3ZpZGVkQ29uZmlnIiwia2V5UGF0aENvbnRleHQiLCJ2YWxpZGF0ZVN0cnVjdHVyZSIsInNldERlZmF1bHRzIiwicnVuQWxsVmFsaWRhdG9yc0luQ29uZmlnVHJlZSIsImdldEV4dGVuc2lvbk5hbWVGcm9tSWQiLCJleHRlbnNpb25Db25maWdTY2hlbWEiLCJuYW1lT2ZTY2hlbWFTb3VyY2UiLCJnZXRQcm92aWRlZENvbmZpZ3MiLCJzbG90TW9kdWxlQ29uZmlnIiwibWVyZ2VDb25maWdzRm9yIiwiY29uZmlnT3ZlcnJpZGUiLCJleHRlbnNpb25TbG90cyIsImNvbmZpZ3VyZSIsImV4dGVuc2lvbkNvbmZpZyIsImNvbWJpbmVkQ29uZmlnIiwibWVyZ2VDb25maWdzIiwicmVzdWx0IiwiZ2V0U2NoZW1hV2l0aFZhbHVlc0FuZFNvdXJjZXMiLCJjb25maWdzQW5kU291cmNlcyIsImMiLCJjcmVhdGVWYWx1ZXNBbmRTb3VyY2VzVHJlZSIsImhhc093blByb3BlcnR5IiwiX3ZhbHVlIiwiX2RlZmF1bHQiLCJfc291cmNlIiwiaXNPcmRpbmFyeU9iamVjdCIsIm9iaiIsImtleSIsImFsbENvbmZpZ3MiLCJzbG90Q29uZmlnUGVyTW9kdWxlIiwidmFsaWRhdGVBbGxFeHRlbnNpb25TbG90Q29uZmlncyIsImNvbmZpZ0J5U2xvdE5hbWUiLCJ2YWxpZGF0ZUV4dGVuc2lvblNsb3RDb25maWciLCJrZXlQYXRoIiwiZXJyb3JQcmVmaXgiLCJpbnZhbGlkS2V5cyIsImZpbHRlciIsImsiLCJpbmNsdWRlcyIsImxlbmd0aCIsImxvZ0Vycm9yIiwiam9pbiIsImFkZCIsIkFycmF5IiwiZXZlcnkiLCJuIiwicmVtb3ZlIiwib3JkZXIiLCJ1cGRhdGVNZXNzYWdlIiwic3RhcnRzV2l0aCIsInRoaXNLZXlQYXRoIiwic2NoZW1hUGFydCIsImVsZW1lbnRzIiwiX2VsZW1lbnRzIiwiaGFzT2JqZWN0U2NoZW1hIiwiX3ZhbGlkYXRvcnMiLCJ2YWx1ZVR5cGUiLCJfdHlwZSIsInZhbHVlcyIsIkpTT04iLCJzdHJpbmdpZnkiLCJpbnB1dENvbmZpZyIsImFsbENvbmZpZ3NGb3JNb2R1bGUiLCJtZXJnZURlZXBBbGwiLCJ2YWx1ZSIsInZhbGlkYXRlQnJhbmNoU3RydWN0dXJlIiwiY2hlY2tUeXBlIiwidmFsaWRhdGVGcmVlZm9ybU9iamVjdFN0cnVjdHVyZSIsInZhbGlkYXRlQXJyYXlTdHJ1Y3R1cmUiLCJmcmVlZm9ybU9iamVjdFNjaGVtYSIsImFycmF5U2NoZW1hIiwidmFsaWRhdGVkQXNBcnJheSIsImkiLCJydW5WYWxpZGF0b3JzIiwiQm9vbGVhbiIsIkNvbmNlcHRVdWlkIiwiTnVtYmVyIiwiU3RyaW5nIiwiVVVJRCIsIlBlcnNvbkF0dHJpYnV0ZVR5cGVVdWlkIiwiUGF0aWVudElkZW50aWZpZXJUeXBlVXVpZCIsInZhbGlkYXRvcnMiLCJyZXR1cm5WYWx1ZSIsInZhbGlkYXRvclJlc3VsdCIsIm1lc3NhZ2UiLCJlIiwiY29uZmlnUGFydCIsImNvbmZpZ1dpdGhEZWZhdWx0cyIsImNvbmYiLCJvYmplY3RLZXkiLCJzZWxlY3RlZENvbmZpZ1BhcnQiLCJlbGVtZW50c1NjaGVtYSIsImRpc3BsYXllZFZhbGlkYXRpb25NZXNzYWdlcyIsIlNldCIsImhhcyIsImNsZWFyQ29uZmlnRXJyb3JzIiwiZm9yRWFjaCIsImRlbGV0ZSIsImNsZWFyIiwicmVzZXRDb25maWdTeXN0ZW0iLCJzcGxpdCIsIl9kZXNjcmlwdGlvbiIsIm8iLCJ0ZXN0IiwiYmFkS2V5cyIsInByaXZpbGVnZXMiLCJleHByZXNzaW9uIiwidW5kZWZpbmVkIl0sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///../../framework/esm-config/dist/module-config/module-config.js\n");
158
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ clearConfigErrors: () => (/* binding */ clearConfigErrors),\n/* harmony export */ defineConfigSchema: () => (/* binding */ defineConfigSchema),\n/* harmony export */ defineExtensionConfigSchema: () => (/* binding */ defineExtensionConfigSchema),\n/* harmony export */ getConfig: () => (/* binding */ getConfig),\n/* harmony export */ getTranslationOverrides: () => (/* binding */ getTranslationOverrides),\n/* harmony export */ processConfig: () => (/* binding */ processConfig),\n/* harmony export */ provide: () => (/* binding */ provide),\n/* harmony export */ registerModuleLoad: () => (/* binding */ registerModuleLoad),\n/* harmony export */ registerModuleWithConfigSystem: () => (/* binding */ registerModuleWithConfigSystem),\n/* harmony export */ registerTranslationNamespace: () => (/* binding */ registerTranslationNamespace),\n/* harmony export */ resetConfigSystem: () => (/* binding */ resetConfigSystem)\n/* harmony export */ });\n/* harmony import */ var ramda__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ramda */ \"../../../node_modules/ramda/es/equals.js\");\n/* harmony import */ var ramda__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ramda */ \"../../../node_modules/ramda/es/mergeDeepRight.js\");\n/* harmony import */ var ramda__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ramda */ \"../../../node_modules/ramda/es/omit.js\");\n/* harmony import */ var ramda__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ramda */ \"../../../node_modules/ramda/es/clone.js\");\n/* harmony import */ var ramda__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ramda */ \"../../../node_modules/ramda/es/reduce.js\");\n/* harmony import */ var _types_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../types.js */ \"../../framework/esm-config/dist/types.js\");\n/* harmony import */ var _validators_type_validators_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../validators/type-validators.js */ \"../../framework/esm-config/dist/validators/type-validators.js\");\n/* harmony import */ var _validators_validator_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../validators/validator.js */ \"../../framework/esm-config/dist/validators/validator.js\");\n/* harmony import */ var _state_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./state.js */ \"../../framework/esm-config/dist/module-config/state.js\");\n/** @module @category Config */ \n\n\n\n\n/**\n * Store setup\n *\n *\n * Set up stores and subscriptions so that inputs get processed appropriately.\n *\n * There are *input* stores and *output* stores. The *input* stores\n * are configInternalStore, temporaryConfigStore, and configExtensionStore. The\n * output stores are set in the `compute...` functions. They are the module\n * config stores, the extension slot config stores (by module), the extension\n * config stores, and the implementer tools config store.\n *\n * This code sets up the subscriptions so that when an input store changes,\n * the correct set of output stores are updated.\n *\n * All `compute...` functions except `computeExtensionConfigs` are pure\n * (or are supposed to be), other than the fact that they all `setState`\n * store values at the end. `computeExtensionConfigs` calls `getGlobalStore`,\n * which creates stores.\n */ // Store unsubscribe functions to allow cleanup (e.g., in tests or hot module reloading)\nconst configSubscriptions = [];\n/**\n * Recomputes all configuration derived stores based on current state of input stores.\n * Called whenever any input store (configInternalStore, temporaryConfigStore, configExtensionStore) changes.\n */ function recomputeAllConfigs() {\n const configState = _state_js__WEBPACK_IMPORTED_MODULE_3__.configInternalStore.getState();\n const tempConfigState = _state_js__WEBPACK_IMPORTED_MODULE_3__.temporaryConfigStore.getState();\n const extensionState = _state_js__WEBPACK_IMPORTED_MODULE_3__.configExtensionStore.getState();\n computeModuleConfig(configState, tempConfigState);\n computeImplementerToolsConfig(configState, tempConfigState);\n computeExtensionSlotConfigs(configState, tempConfigState);\n computeExtensionConfigs(configState, extensionState, tempConfigState);\n}\nfunction setupConfigSubscriptions() {\n // Initial computation\n recomputeAllConfigs();\n // Subscribe to all input stores with a single handler\n // This ensures we only recompute once even if multiple stores change simultaneously\n configSubscriptions.push(_state_js__WEBPACK_IMPORTED_MODULE_3__.configInternalStore.subscribe(recomputeAllConfigs));\n configSubscriptions.push(_state_js__WEBPACK_IMPORTED_MODULE_3__.temporaryConfigStore.subscribe(recomputeAllConfigs));\n configSubscriptions.push(_state_js__WEBPACK_IMPORTED_MODULE_3__.configExtensionStore.subscribe(recomputeAllConfigs));\n}\n// Set up subscriptions at module load time\nsetupConfigSubscriptions();\nfunction computeModuleConfig(state, tempState) {\n for (let moduleName of Object.keys(state.schemas)){\n // At this point the schema could be either just the implicit schema or the actually\n // defined schema. We run with just the implicit schema because we want to populate\n // the config store with the translation overrides as soon as possible. In fact, the\n // translation system will throw for Suspense until the translation overrides are\n // available, which as of this writing blocks the schema definition from occurring\n // for modules loaded based on their extensions.\n const moduleStore = (0,_state_js__WEBPACK_IMPORTED_MODULE_3__.getConfigStore)(moduleName);\n let newState;\n if (state.moduleLoaded[moduleName]) {\n const config = getConfigForModule(moduleName, state, tempState);\n newState = {\n translationOverridesLoaded: true,\n loaded: true,\n config\n };\n } else {\n const config = getConfigForModuleImplicitSchema(moduleName, state, tempState);\n newState = {\n translationOverridesLoaded: true,\n loaded: false,\n config\n };\n }\n moduleStore.setState(newState);\n }\n}\nfunction computeExtensionSlotConfigs(state, tempState) {\n const slotConfigs = getExtensionSlotConfigs(state, tempState);\n const newSlotStoreEntries = Object.fromEntries(Object.entries(slotConfigs).map(([slotName, config])=>[\n slotName,\n {\n loaded: true,\n config\n }\n ]));\n const slotStore = (0,_state_js__WEBPACK_IMPORTED_MODULE_3__.getExtensionSlotsConfigStore)();\n const oldState = slotStore.getState();\n const newState = {\n slots: {\n ...oldState.slots,\n ...newSlotStoreEntries\n }\n };\n if (!(0,ramda__WEBPACK_IMPORTED_MODULE_4__[\"default\"])(oldState.slots, newState.slots)) {\n slotStore.setState(newState);\n }\n}\nfunction computeImplementerToolsConfig(state, tempConfigState) {\n const oldState = _state_js__WEBPACK_IMPORTED_MODULE_3__.implementerToolsConfigStore.getState();\n const config = getImplementerToolsConfig(state, tempConfigState);\n const newState = {\n config\n };\n // Use deep equality on the actual config content, not the wrapper object\n if (!(0,ramda__WEBPACK_IMPORTED_MODULE_4__[\"default\"])(oldState.config, newState.config)) {\n _state_js__WEBPACK_IMPORTED_MODULE_3__.implementerToolsConfigStore.setState(newState);\n }\n}\nfunction computeExtensionConfigs(configState, extensionState, tempConfigState) {\n const configs = {};\n // We assume that the module schema has already been defined, since the extension\n // it contains is mounted.\n for (let extension of extensionState.mountedExtensions){\n const config = computeExtensionConfig(extension.slotModuleName, extension.extensionModuleName, extension.slotName, extension.extensionId, configState, tempConfigState);\n if (!configs[extension.slotName]) {\n configs[extension.slotName] = {};\n }\n configs[extension.slotName][extension.extensionId] = {\n config,\n loaded: true\n };\n }\n const extensionsConfigStore = (0,_state_js__WEBPACK_IMPORTED_MODULE_3__.getExtensionsConfigStore)();\n const oldState = extensionsConfigStore.getState();\n const newState = {\n configs\n };\n // Use deep equality to only update if configs actually changed\n if (!(0,ramda__WEBPACK_IMPORTED_MODULE_4__[\"default\"])(oldState.configs, newState.configs)) {\n extensionsConfigStore.setState(newState);\n }\n}\n/*\n * API\n *\n */ /**\n * This defines a configuration schema for a module. The schema tells the\n * configuration system how the module can be configured. It specifies\n * what makes configuration valid or invalid.\n *\n * See [Configuration System](https://o3-docs.openmrs.org/docs/configuration-system)\n * for more information about defining a config schema.\n *\n * @param moduleName Name of the module the schema is being defined for. Generally\n * should be the one in which the `defineConfigSchema` call takes place.\n * @param schema The config schema for the module\n */ function defineConfigSchema(moduleName, schema) {\n validateConfigSchema(moduleName, schema);\n const enhancedSchema = (0,ramda__WEBPACK_IMPORTED_MODULE_5__[\"default\"])(schema, implicitConfigSchema);\n _state_js__WEBPACK_IMPORTED_MODULE_3__.configInternalStore.setState((state)=>({\n ...state,\n schemas: {\n ...state.schemas,\n [moduleName]: enhancedSchema\n },\n moduleLoaded: {\n ...state.moduleLoaded,\n [moduleName]: true\n }\n }));\n}\n/**\n * This alerts the configuration system that a module exists. This allows config to be\n * processed, while still allowing the extension system to know whether the module has\n * actually had its front bundle executed yet.\n *\n * This should only be used in esm-app-shell.\n *\n * @internal\n * @param moduleName\n */ function registerModuleWithConfigSystem(moduleName) {\n _state_js__WEBPACK_IMPORTED_MODULE_3__.configInternalStore.setState((state)=>({\n ...state,\n schemas: {\n ...state.schemas,\n [moduleName]: implicitConfigSchema\n }\n }));\n}\n/**\n * This alerts the configuration system that a module has been loaded.\n *\n * This should only be used in esm-app-shell.\n *\n * @internal\n * @param moduleName\n */ function registerModuleLoad(moduleName) {\n _state_js__WEBPACK_IMPORTED_MODULE_3__.configInternalStore.setState((state)=>({\n ...state,\n moduleLoaded: {\n ...state.moduleLoaded,\n [moduleName]: true\n }\n }));\n}\n/**\n * This allows the config system to support translation overrides for namespaces that\n * do not correspond to modules.\n *\n * This should only be used in esm-app-shell.\n *\n * @internal\n * @param namespace\n */ function registerTranslationNamespace(namespace) {\n _state_js__WEBPACK_IMPORTED_MODULE_3__.configInternalStore.setState((state)=>({\n ...state,\n schemas: {\n ...state.schemas,\n [namespace]: translationOverridesSchema\n }\n }));\n}\n/**\n * This defines a configuration schema for an extension. When a schema is defined\n * for an extension, that extension will receive the configuration corresponding\n * to that schema, rather than the configuration corresponding to the module\n * in which it is defined.\n *\n * The schema tells the configuration system how the module can be configured.\n * It specifies what makes configuration valid or invalid.\n *\n * See [Configuration System](https://o3-docs.openmrs.org/docs/configuration-system)\n * for more information about defining a config schema.\n *\n * @param extensionName Name of the extension the schema is being defined for.\n * Should match the `name` of one of the `extensions` entries defined in\n * the app's `routes.json` file.\n * @param schema The config schema for the extension\n */ function defineExtensionConfigSchema(extensionName, schema) {\n validateConfigSchema(extensionName, schema);\n const enhancedSchema = (0,ramda__WEBPACK_IMPORTED_MODULE_5__[\"default\"])(schema, implicitConfigSchema);\n const state = _state_js__WEBPACK_IMPORTED_MODULE_3__.configInternalStore.getState();\n if (state.schemas[extensionName]) {\n console.error(`Config schema for extension ${extensionName} already exists. If there are multiple extensions with this same name, one will probably crash.`);\n }\n _state_js__WEBPACK_IMPORTED_MODULE_3__.configInternalStore.setState((state)=>({\n ...state,\n schemas: {\n ...state.schemas,\n [extensionName]: enhancedSchema\n }\n }));\n}\nfunction provide(config, sourceName = 'provided') {\n _state_js__WEBPACK_IMPORTED_MODULE_3__.configInternalStore.setState((state)=>({\n ...state,\n providedConfigs: [\n ...state.providedConfigs,\n {\n source: sourceName,\n config\n }\n ]\n }));\n}\n/**\n * A promise-based way to access the config as soon as it is fully loaded.\n * If it is already loaded, resolves the config in its present state.\n *\n * This is a useful function if you need to get the config in the course\n * of the execution of a function.\n *\n * @param moduleName The name of the module for which to look up the config\n */ function getConfig(moduleName) {\n return new Promise((resolve)=>{\n const store = (0,_state_js__WEBPACK_IMPORTED_MODULE_3__.getConfigStore)(moduleName);\n function update(state) {\n if (state.loaded && state.config) {\n const config = (0,ramda__WEBPACK_IMPORTED_MODULE_6__[\"default\"])([\n 'Display conditions',\n 'Translation overrides'\n ], state.config);\n resolve(config);\n if (unsubscribe) {\n unsubscribe();\n }\n }\n }\n update(store.getState());\n const unsubscribe = store.subscribe(update);\n });\n}\n/** @internal */ function getTranslationOverrides(moduleName, slotName, extensionId) {\n const promises = [\n new Promise((resolve)=>{\n const configStore = (0,_state_js__WEBPACK_IMPORTED_MODULE_3__.getConfigStore)(moduleName);\n function update(state) {\n if (state.translationOverridesLoaded && state.config) {\n const translationOverrides = state.config['Translation overrides'] ?? {};\n resolve(translationOverrides);\n if (unsubscribe) {\n unsubscribe();\n }\n }\n }\n update(configStore.getState());\n const unsubscribe = configStore.subscribe(update);\n })\n ];\n if (slotName && extensionId) {\n promises.push(new Promise((resolve)=>{\n const configStore = (0,_state_js__WEBPACK_IMPORTED_MODULE_3__.getExtensionConfig)(slotName, extensionId);\n function update(state) {\n if (state.loaded && state.config) {\n const translationOverrides = state.config['Translation overrides'] ?? {};\n resolve(translationOverrides);\n if (unsubscribe) {\n unsubscribe();\n }\n }\n }\n update(configStore.getState());\n const unsubscribe = configStore.subscribe(update);\n }));\n }\n return Promise.all(promises);\n}\n/**\n * Validate and interpolate defaults for `providedConfig` according to `schema`\n *\n * @param schema a configuration schema\n * @param providedConfig an object of config values (without the top-level module name)\n * @param keyPathContext a dot-deparated string which helps the user figure out where\n * the provided config came from\n * @internal\n */ function processConfig(schema, providedConfig, keyPathContext) {\n validateStructure(schema, providedConfig, keyPathContext);\n const config = setDefaults(schema, providedConfig);\n runAllValidatorsInConfigTree(schema, config, keyPathContext);\n return config;\n}\n/*\n * Helper functions\n *\n */ /**\n * Returns the configuration for an extension. This configuration is specific\n * to the slot in which it is mounted, and its ID within that slot.\n *\n * The schema for that configuration is the extension schema. If no extension\n * schema has been provided, the schema used is the schema of the module in\n * which the extension is defined.\n *\n * @param slotModuleName The name of the module which defines the extension slot\n * @param extensionModuleName The name of the module which defines the extension (and therefore the config schema)\n * @param slotName The name of the extension slot where the extension is mounted\n * @param extensionId The ID of the extension in its slot\n */ function computeExtensionConfig(slotModuleName, extensionModuleName, slotName, extensionId, configState, tempConfigState) {\n const extensionName = getExtensionNameFromId(extensionId);\n const extensionConfigSchema = configState.schemas[extensionName];\n const nameOfSchemaSource = extensionConfigSchema ? extensionName : extensionModuleName;\n const providedConfigs = getProvidedConfigs(configState, tempConfigState);\n const slotModuleConfig = mergeConfigsFor(slotModuleName, providedConfigs);\n const configOverride = slotModuleConfig?.extensionSlots?.[slotName]?.configure?.[extensionId] ?? {};\n const extensionConfig = mergeConfigsFor(nameOfSchemaSource, providedConfigs);\n const combinedConfig = mergeConfigs([\n extensionConfig,\n configOverride\n ]);\n const schema = extensionConfigSchema ?? configState.schemas[extensionModuleName];\n validateStructure(schema, combinedConfig, nameOfSchemaSource);\n const config = setDefaults(schema, combinedConfig);\n runAllValidatorsInConfigTree(schema, config, nameOfSchemaSource);\n delete config.extensionSlots;\n return config;\n}\nfunction getImplementerToolsConfig(configState, tempConfigState) {\n let result = getSchemaWithValuesAndSources((0,ramda__WEBPACK_IMPORTED_MODULE_7__[\"default\"])(configState.schemas));\n const configsAndSources = [\n ...configState.providedConfigs.map((c)=>[\n c.config,\n c.source\n ]),\n [\n tempConfigState.config,\n 'temporary config'\n ]\n ];\n for (let [config, source] of configsAndSources){\n result = mergeConfigs([\n result,\n createValuesAndSourcesTree(config, source)\n ]);\n }\n return result;\n}\nfunction getSchemaWithValuesAndSources(schema) {\n if (schema.hasOwnProperty('_default')) {\n return {\n ...schema,\n _value: schema._default,\n _source: 'default'\n };\n } else if (isOrdinaryObject(schema)) {\n return Object.keys(schema).reduce((obj, key)=>{\n obj[key] = getSchemaWithValuesAndSources(schema[key]);\n return obj;\n }, {});\n } else {\n // at this point, the schema is bad and an error will have been logged during schema validation\n return {};\n }\n}\nfunction createValuesAndSourcesTree(config, source) {\n if (isOrdinaryObject(config)) {\n return Object.keys(config).reduce((obj, key)=>{\n obj[key] = createValuesAndSourcesTree(config[key], source);\n return obj;\n }, {});\n } else {\n return {\n _value: config,\n _source: source\n };\n }\n}\nfunction getExtensionSlotConfigs(configState, tempConfigState) {\n const allConfigs = mergeConfigs(getProvidedConfigs(configState, tempConfigState));\n const slotConfigPerModule = Object.keys(allConfigs).reduce((obj, key)=>{\n if (allConfigs[key]?.extensionSlots) {\n obj[key] = allConfigs[key]?.extensionSlots;\n }\n return obj;\n }, {});\n validateAllExtensionSlotConfigs(slotConfigPerModule);\n const slotConfigs = Object.keys(slotConfigPerModule).reduce((obj, key)=>{\n obj = {\n ...obj,\n ...slotConfigPerModule[key]\n };\n return obj;\n }, {});\n return slotConfigs;\n}\nfunction validateAllExtensionSlotConfigs(slotConfigPerModule) {\n for (let [moduleName, configBySlotName] of Object.entries(slotConfigPerModule)){\n for (let [slotName, config] of Object.entries(configBySlotName)){\n validateExtensionSlotConfig(config, moduleName, slotName);\n }\n }\n}\nfunction validateExtensionSlotConfig(config, moduleName, slotName) {\n const keyPath = `${moduleName}.extensionSlots.${slotName}`;\n const errorPrefix = `Extension slot config '${keyPath}'`;\n const invalidKeys = Object.keys(config).filter((k)=>![\n 'add',\n 'remove',\n 'order',\n 'configure'\n ].includes(k));\n if (invalidKeys.length) {\n logError(keyPath, errorPrefix + `' contains invalid keys '${invalidKeys.join(\"', '\")}'`);\n }\n if (config.add) {\n if (!Array.isArray(config.add) || !config.add.every((n)=>typeof n === 'string')) {\n logError(keyPath, errorPrefix + `.add' is invalid. Must be an array of strings (extension IDs)`);\n }\n }\n if (config.remove) {\n if (!Array.isArray(config.remove) || !config.remove.every((n)=>typeof n === 'string')) {\n logError(keyPath, errorPrefix + `.remove' is invalid. Must be an array of strings (extension IDs)`);\n }\n }\n if (config.order) {\n if (!Array.isArray(config.order) || !config.order.every((n)=>typeof n === 'string')) {\n logError(keyPath, errorPrefix + `.order' is invalid. Must be an array of strings (extension IDs)`);\n }\n }\n if (config.configure) {\n if (!isOrdinaryObject(config.configure)) {\n logError(keyPath, errorPrefix + `.configure' is invalid. Must be an object with extension IDs for keys`);\n }\n }\n}\nfunction getProvidedConfigs(configState, tempConfigState) {\n return [\n ...configState.providedConfigs.map((c)=>c.config),\n tempConfigState.config\n ];\n}\n/**\n * Validates the config schema for a module. Since problems identified here are programming errors\n * that hopefully will be caught during development, this function logs errors to the console directly;\n * it's fine if we spam the user with these errors.\n */ function validateConfigSchema(moduleName, schema, keyPath = '') {\n const updateMessage = `Please verify that you are running the latest version and, if so, alert the maintainer.`;\n for (const key of Object.keys(schema).filter((k)=>!k.startsWith('_'))){\n const thisKeyPath = keyPath + (keyPath && '.') + key;\n const schemaPart = schema[key];\n if (thisKeyPath === 'Display conditions') {\n console.error(`${moduleName} declares a configuration option called \"Display conditions\"; the \"Display conditions\" option is a reserved name. ${updateMessage}`);\n }\n if (thisKeyPath === 'Translation overrides') {\n console.error(`${moduleName} declares a configuration option called \"Translation overrides\"; the \"Translation overrides\" option is a reserved name. ${updateMessage}`);\n }\n if (!isOrdinaryObject(schemaPart)) {\n console.error(`${moduleName} has bad config schema definition for key '${thisKeyPath}'. ${updateMessage}`);\n continue;\n }\n if (!schemaPart.hasOwnProperty('_default')) {\n // recurse for nested config keys\n validateConfigSchema(moduleName, schemaPart, thisKeyPath);\n }\n const elements = schemaPart._elements;\n if (hasObjectSchema(elements)) {\n validateConfigSchema(moduleName, elements, thisKeyPath + '._elements');\n }\n if (schemaPart._validators) {\n for (let validator of schemaPart._validators){\n if (typeof validator !== 'function') {\n console.error(`${moduleName} has invalid validator for key '${thisKeyPath}' ${updateMessage}.` + `\\n\\nIf you're the maintainer: validators must be functions that return either ` + `undefined or an error string. Received ${validator}.`);\n }\n }\n }\n const valueType = schemaPart._type;\n if (valueType && !Object.values(_types_js__WEBPACK_IMPORTED_MODULE_0__.Type).includes(valueType)) {\n console.error(`${moduleName} has invalid type for key '${thisKeyPath}' ${updateMessage}.` + `\\n\\nIf you're the maintainer: the allowed types are ${Object.values(_types_js__WEBPACK_IMPORTED_MODULE_0__.Type).join(', ')}. ` + `Received '${valueType}'`);\n }\n if (Object.keys(schemaPart).every((k)=>[\n '_description',\n '_validators',\n '_elements',\n '_type'\n ].includes(k)) && !keyPath.includes('._elements')) {\n console.error(`${moduleName} has bad config schema definition for key '${thisKeyPath}'. ${updateMessage}.` + `\\n\\nIf you're the maintainer: all config elements must have a default. ` + `Received ${JSON.stringify(schemaPart)}`);\n }\n if (elements && valueType && ![\n _types_js__WEBPACK_IMPORTED_MODULE_0__.Type.Array,\n _types_js__WEBPACK_IMPORTED_MODULE_0__.Type.Object\n ].includes(valueType)) {\n console.error(`${moduleName} has bad config schema definition for key '${thisKeyPath}'. ${updateMessage}.` + `\\n\\nIf you're the maintainer: the 'elements' key only works with '_type' equal to 'Array' or 'Object'. ` + `Received ${JSON.stringify(valueType)}`);\n }\n }\n}\nfunction getConfigForModule(moduleName, configState, tempConfigState) {\n const schema = configState.schemas[moduleName];\n const inputConfig = mergeConfigsFor(moduleName, getProvidedConfigs(configState, tempConfigState));\n validateStructure(schema, inputConfig, moduleName);\n const config = setDefaults(schema, inputConfig);\n runAllValidatorsInConfigTree(schema, config, moduleName);\n delete config.extensionSlots;\n return config;\n}\nfunction getConfigForModuleImplicitSchema(moduleName, configState, tempConfigState) {\n const inputConfig = mergeConfigsFor(moduleName, getProvidedConfigs(configState, tempConfigState));\n const config = setDefaults(implicitConfigSchema, inputConfig);\n runAllValidatorsInConfigTree(implicitConfigSchema, config, moduleName);\n delete config.extensionSlots;\n return config;\n}\nfunction mergeConfigsFor(moduleName, allConfigs) {\n const allConfigsForModule = allConfigs.map(({ [moduleName]: c })=>c).filter((c)=>!!c);\n return mergeConfigs(allConfigsForModule);\n}\nfunction mergeConfigs(configs) {\n const mergeDeepAll = (0,ramda__WEBPACK_IMPORTED_MODULE_8__[\"default\"])(ramda__WEBPACK_IMPORTED_MODULE_5__[\"default\"]);\n return mergeDeepAll({}, configs);\n}\n/**\n * Recursively check the provided config tree to make sure that all\n * of the provided properties exist in the schema, and that types are\n * correct. Does not run validators yet, since those will be run on\n * the config with the defaults filled in.\n */ function validateStructure(schema, config, keyPath = '') {\n // validate each constituent element\n for (const key of Object.keys(config)){\n const value = config[key];\n const thisKeyPath = keyPath + '.' + key;\n const schemaPart = schema[key];\n if (!schema.hasOwnProperty(key)) {\n if (!(key === 'extensionSlots' && keyPath !== '')) {\n logError(thisKeyPath, `Unknown config key '${thisKeyPath}' provided. Ignoring.`);\n }\n continue;\n }\n validateBranchStructure(schemaPart, value, thisKeyPath);\n }\n}\nfunction validateBranchStructure(schemaPart, value, keyPath) {\n checkType(keyPath, schemaPart._type, value);\n if (isOrdinaryObject(value)) {\n if (schemaPart._type === _types_js__WEBPACK_IMPORTED_MODULE_0__.Type.Object) {\n // validate as freeform object\n validateFreeformObjectStructure(schemaPart, value, keyPath);\n } else if (!(schemaPart.hasOwnProperty('_default') || schemaPart.hasOwnProperty('_type'))) {\n // validate as normal nested config\n validateStructure(schemaPart, value, keyPath);\n }\n } else {\n if (schemaPart._type === _types_js__WEBPACK_IMPORTED_MODULE_0__.Type.Array) {\n validateArrayStructure(schemaPart, value, keyPath);\n }\n }\n}\nfunction validateFreeformObjectStructure(freeformObjectSchema, config, keyPath) {\n if (freeformObjectSchema._elements) {\n for (const key of Object.keys(config)){\n const value = config[key];\n validateBranchStructure(freeformObjectSchema._elements, value, `${keyPath}.${key}`);\n }\n }\n}\nfunction validateArrayStructure(arraySchema, value, keyPath) {\n const validatedAsArray = checkType(keyPath, _types_js__WEBPACK_IMPORTED_MODULE_0__.Type.Array, value);\n if (!validatedAsArray) {\n return;\n }\n // if there is an array element object schema, verify that elements match it\n if (hasObjectSchema(arraySchema._elements)) {\n for(let i = 0; i < value.length; i++){\n validateBranchStructure(arraySchema._elements, value[i], `${keyPath}[${i}]`);\n }\n }\n for(let i = 0; i < value.length; i++){\n checkType(`${keyPath}[${i}]`, arraySchema._elements?._type, value[i]);\n }\n}\n/**\n * Run all the validators in the config tree. This should be run\n * on the config object after it has been filled in with all the defaults, since\n * higher-level validators may refer to default values.\n */ function runAllValidatorsInConfigTree(schema, config, keyPath = '') {\n // If `!schema`, there should have been a structural validation error printed already.\n if (schema) {\n if (config !== schema._default) {\n runValidators(keyPath, schema._validators, config);\n }\n if (isOrdinaryObject(config)) {\n for (const key of Object.keys(config)){\n const value = config[key];\n const thisKeyPath = keyPath + '.' + key;\n const schemaPart = schema[key];\n if (schema._type === _types_js__WEBPACK_IMPORTED_MODULE_0__.Type.Object && schema._elements) {\n runAllValidatorsInConfigTree(schema._elements, value, thisKeyPath);\n } else {\n runAllValidatorsInConfigTree(schemaPart, value, thisKeyPath);\n }\n }\n } else if (Array.isArray(config) && schema._elements) {\n for(let i = 0; i < config.length; i++){\n runAllValidatorsInConfigTree(schema._elements, config[i], `${keyPath}[${i}]`);\n }\n }\n }\n}\n/**\n * Run type validation for the value, logging any errors.\n * @returns true if validation passes, false otherwise\n */ function checkType(keyPath, _type, value) {\n if (_type) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\n const validator = {\n Array: _validators_type_validators_js__WEBPACK_IMPORTED_MODULE_1__.isArray,\n Boolean: _validators_type_validators_js__WEBPACK_IMPORTED_MODULE_1__.isBoolean,\n ConceptUuid: _validators_type_validators_js__WEBPACK_IMPORTED_MODULE_1__.isUuid,\n Number: _validators_type_validators_js__WEBPACK_IMPORTED_MODULE_1__.isNumber,\n Object: _validators_type_validators_js__WEBPACK_IMPORTED_MODULE_1__.isObject,\n String: _validators_type_validators_js__WEBPACK_IMPORTED_MODULE_1__.isString,\n UUID: _validators_type_validators_js__WEBPACK_IMPORTED_MODULE_1__.isUuid,\n PersonAttributeTypeUuid: _validators_type_validators_js__WEBPACK_IMPORTED_MODULE_1__.isUuid,\n PatientIdentifierTypeUuid: _validators_type_validators_js__WEBPACK_IMPORTED_MODULE_1__.isUuid\n };\n return runValidators(keyPath, [\n validator[_type]\n ], value);\n }\n return true;\n}\n/**\n * Runs validators, logging errors.\n * @returns true if all pass, false otherwise.\n */ // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\nfunction runValidators(keyPath, validators, value) {\n let returnValue = true;\n if (validators) {\n try {\n for (let validator of validators){\n const validatorResult = validator(value);\n if (typeof validatorResult === 'string') {\n const message = typeof value === 'object' ? `Invalid configuration for ${keyPath}: ${validatorResult}` : `Invalid configuration value ${value} for ${keyPath}: ${validatorResult}`;\n logError(keyPath, message);\n returnValue = false;\n }\n }\n } catch (e) {\n console.error(`Skipping invalid validator at \"${keyPath}\". Encountered error\\n\\t${e}`);\n }\n }\n return returnValue;\n}\n// Recursively fill in the config with values from the schema.\nconst setDefaults = (schema, inputConfig)=>{\n const config = (0,ramda__WEBPACK_IMPORTED_MODULE_7__[\"default\"])(inputConfig);\n if (!schema) {\n return config;\n }\n for (const key of Object.keys(schema)){\n const configPart = config[key];\n const schemaPart = schema[key];\n // The `schemaPart &&` clause of this `if` statement will only fail\n // if the schema is very invalid. It is there to prevent the app from\n // crashing completely, though it will produce unexpected behavior.\n // If this happens, there should be legible errors in the console from\n // the schema validator.\n if (schemaPart && (schemaPart.hasOwnProperty('_type') || schemaPart.hasOwnProperty('_default'))) {\n // We assume that schemaPart defines a config value, since it has\n // a property `_type` or `_default`.\n if (!config.hasOwnProperty(key)) {\n config[key] = schemaPart['_default'];\n }\n // We also check if it is an object or array with object elements, in which case we recurse\n const elements = schemaPart._elements;\n if (configPart && hasObjectSchema(elements)) {\n if (schemaPart._type === _types_js__WEBPACK_IMPORTED_MODULE_0__.Type.Array && Array.isArray(configPart)) {\n const configWithDefaults = configPart.map((conf)=>setDefaults(elements, conf));\n config[key] = configWithDefaults;\n } else if (schemaPart._type === _types_js__WEBPACK_IMPORTED_MODULE_0__.Type.Object) {\n for (let objectKey of Object.keys(configPart)){\n configPart[objectKey] = setDefaults(elements, configPart[objectKey]);\n }\n }\n }\n } else if (isOrdinaryObject(schemaPart)) {\n // Since schemaPart has no property \"_type\", if it's an ordinary object\n // (unlike, importantly, the validators array), we assume it is a parent config property.\n // We recurse to config[key] and schema[key]. Default config[key] to {}.\n const selectedConfigPart = configPart ?? {};\n // There will have been a validation error already if configPart is not a plain object.\n if (isOrdinaryObject(selectedConfigPart)) {\n config[key] = setDefaults(schemaPart, selectedConfigPart);\n }\n }\n }\n return config;\n};\nfunction hasObjectSchema(elementsSchema) {\n return !!elementsSchema && Object.keys(elementsSchema).filter((e)=>![\n '_default',\n '_validators'\n ].includes(e)).length > 0;\n}\nfunction isOrdinaryObject(value) {\n return typeof value === 'object' && !Array.isArray(value) && value !== null;\n}\n/** Keep track of which validation errors we have displayed. Each one should only be displayed once. */ let displayedValidationMessages = new Set();\nfunction logError(keyPath, message) {\n const key = `${keyPath}:::${message}`;\n // technically, this should not be possible, but because of how things wind-up transpiled, this isn't impossible\n if (!displayedValidationMessages) {\n displayedValidationMessages = new Set();\n }\n if (!displayedValidationMessages.has(key)) {\n console.error(message);\n displayedValidationMessages.add(key);\n }\n}\n/**\n * Normally, configuration errors are only displayed once. This function clears the list of\n * displayed errors, so that they will be displayed again.\n *\n * @internal\n */ function clearConfigErrors(keyPath) {\n if (keyPath) {\n displayedValidationMessages.forEach((key)=>{\n if (key.startsWith(keyPath)) {\n displayedValidationMessages.delete(key);\n }\n });\n } else {\n displayedValidationMessages.clear();\n }\n}\n/**\n * Cleans up all config store subscriptions and re-establishes them. This is primarily\n * useful for testing, where subscriptions set up at module load time need to be cleared\n * between tests to prevent infinite update loops. After clearing, subscriptions are\n * re-established so the config system continues to work normally.\n *\n * @internal\n */ function resetConfigSystem() {\n configSubscriptions.forEach((unsubscribe)=>unsubscribe());\n configSubscriptions.length = 0;\n setupConfigSubscriptions();\n}\n/**\n * Copied over from esm-extensions. It rightly belongs to that module, but esm-config\n * cannot depend on esm-extensions.\n */ function getExtensionNameFromId(extensionId) {\n const [extensionName] = extensionId.split('#');\n return extensionName;\n}\n/**\n * The translation overrides schema is used in the implicit schema given to every module;\n * plus any additional translation namespaces (at time of writing, this is just 'core').\n */ const translationOverridesSchema = {\n 'Translation overrides': {\n _description: 'Per-language overrides for frontend translations should be keyed by language code and each language dictionary contains the translation key and the display value',\n _type: _types_js__WEBPACK_IMPORTED_MODULE_0__.Type.Object,\n _default: {},\n _validators: [\n (0,_validators_validator_js__WEBPACK_IMPORTED_MODULE_2__.validator)((o)=>Object.keys(o).every((k)=>/^[a-z]{2,3}(-[A-Z]{2,3})?$/.test(k)), (o)=>{\n const badKeys = Object.keys(o).filter((k)=>!/^[a-z]{2,3}(-[A-Z]{2,3})?$/.test(k));\n return `The 'Translation overrides' object should have language codes for keys. Language codes must be in the form of a two-to-three letter language code optionally followed by a hyphen and a two-to-three letter country code. The following keys do not conform: ${badKeys.join(', ')}.`;\n })\n ]\n }\n};\n/**\n * The implicitConfigSchema is implicitly included in every configuration schema\n */ const implicitConfigSchema = {\n 'Display conditions': {\n privileges: {\n _description: 'The privilege(s) the user must have to use this extension',\n _type: _types_js__WEBPACK_IMPORTED_MODULE_0__.Type.Array,\n _default: []\n },\n expression: {\n _description: 'The expression that determines whether the extension is displayed',\n _type: _types_js__WEBPACK_IMPORTED_MODULE_0__.Type.String,\n _default: undefined\n }\n },\n ...translationOverridesSchema\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi4vLi4vZnJhbWV3b3JrL2VzbS1jb25maWcvZGlzdC9tb2R1bGUtY29uZmlnL21vZHVsZS1jb25maWcuanMiLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSw2QkFBNkIsR0FBdUU7QUFDakU7QUFDeUU7QUFDckQ7QUFDK0o7QUFDdE47Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Q0FtQkMsR0FBRyx3RkFBd0Y7QUFDNUYsTUFBTXFCLHNCQUFzQixFQUFFO0FBQzlCOzs7Q0FHQyxHQUFHLFNBQVNDO0lBQ1QsTUFBTUMsY0FBY1QsMERBQW1CQSxDQUFDVSxRQUFRO0lBQ2hELE1BQU1DLGtCQUFrQkwsMkRBQW9CQSxDQUFDSSxRQUFRO0lBQ3JELE1BQU1FLGlCQUFpQmIsMkRBQW9CQSxDQUFDVyxRQUFRO0lBQ3BERyxvQkFBb0JKLGFBQWFFO0lBQ2pDRyw4QkFBOEJMLGFBQWFFO0lBQzNDSSw0QkFBNEJOLGFBQWFFO0lBQ3pDSyx3QkFBd0JQLGFBQWFHLGdCQUFnQkQ7QUFDekQ7QUFDQSxTQUFTTTtJQUNMLHNCQUFzQjtJQUN0QlQ7SUFDQSxzREFBc0Q7SUFDdEQsb0ZBQW9GO0lBQ3BGRCxvQkFBb0JXLElBQUksQ0FBQ2xCLDBEQUFtQkEsQ0FBQ21CLFNBQVMsQ0FBQ1g7SUFDdkRELG9CQUFvQlcsSUFBSSxDQUFDWiwyREFBb0JBLENBQUNhLFNBQVMsQ0FBQ1g7SUFDeERELG9CQUFvQlcsSUFBSSxDQUFDbkIsMkRBQW9CQSxDQUFDb0IsU0FBUyxDQUFDWDtBQUM1RDtBQUNBLDJDQUEyQztBQUMzQ1M7QUFDQSxTQUFTSixvQkFBb0JPLEtBQUssRUFBRUMsU0FBUztJQUN6QyxLQUFLLElBQUlDLGNBQWNDLE9BQU9DLElBQUksQ0FBQ0osTUFBTUssT0FBTyxFQUFFO1FBQzlDLG9GQUFvRjtRQUNwRixtRkFBbUY7UUFDbkYsb0ZBQW9GO1FBQ3BGLGlGQUFpRjtRQUNqRixrRkFBa0Y7UUFDbEYsZ0RBQWdEO1FBQ2hELE1BQU1DLGNBQWN6Qix5REFBY0EsQ0FBQ3FCO1FBQ25DLElBQUlLO1FBQ0osSUFBSVAsTUFBTVEsWUFBWSxDQUFDTixXQUFXLEVBQUU7WUFDaEMsTUFBTU8sU0FBU0MsbUJBQW1CUixZQUFZRixPQUFPQztZQUNyRE0sV0FBVztnQkFDUEksNEJBQTRCO2dCQUM1QkMsUUFBUTtnQkFDUkg7WUFDSjtRQUNKLE9BQU87WUFDSCxNQUFNQSxTQUFTSSxpQ0FBaUNYLFlBQVlGLE9BQU9DO1lBQ25FTSxXQUFXO2dCQUNQSSw0QkFBNEI7Z0JBQzVCQyxRQUFRO2dCQUNSSDtZQUNKO1FBQ0o7UUFDQUgsWUFBWVEsUUFBUSxDQUFDUDtJQUN6QjtBQUNKO0FBQ0EsU0FBU1osNEJBQTRCSyxLQUFLLEVBQUVDLFNBQVM7SUFDakQsTUFBTWMsY0FBY0Msd0JBQXdCaEIsT0FBT0M7SUFDbkQsTUFBTWdCLHNCQUFzQmQsT0FBT2UsV0FBVyxDQUFDZixPQUFPZ0IsT0FBTyxDQUFDSixhQUFhSyxHQUFHLENBQUMsQ0FBQyxDQUFDQyxVQUFVWixPQUFPLEdBQUc7WUFDN0ZZO1lBQ0E7Z0JBQ0lULFFBQVE7Z0JBQ1JIO1lBQ0o7U0FDSDtJQUNMLE1BQU1hLFlBQVl2Qyx1RUFBNEJBO0lBQzlDLE1BQU13QyxXQUFXRCxVQUFVaEMsUUFBUTtJQUNuQyxNQUFNaUIsV0FBVztRQUNiaUIsT0FBTztZQUNILEdBQUdELFNBQVNDLEtBQUs7WUFDakIsR0FBR1AsbUJBQW1CO1FBQzFCO0lBQ0o7SUFDQSxJQUFJLENBQUNsRCxpREFBTUEsQ0FBQ3dELFNBQVNDLEtBQUssRUFBRWpCLFNBQVNpQixLQUFLLEdBQUc7UUFDekNGLFVBQVVSLFFBQVEsQ0FBQ1A7SUFDdkI7QUFDSjtBQUNBLFNBQVNiLDhCQUE4Qk0sS0FBSyxFQUFFVCxlQUFlO0lBQ3pELE1BQU1nQyxXQUFXdEMsa0VBQTJCQSxDQUFDSyxRQUFRO0lBQ3JELE1BQU1tQixTQUFTZ0IsMEJBQTBCekIsT0FBT1Q7SUFDaEQsTUFBTWdCLFdBQVc7UUFDYkU7SUFDSjtJQUNBLHlFQUF5RTtJQUN6RSxJQUFJLENBQUMxQyxpREFBTUEsQ0FBQ3dELFNBQVNkLE1BQU0sRUFBRUYsU0FBU0UsTUFBTSxHQUFHO1FBQzNDeEIsa0VBQTJCQSxDQUFDNkIsUUFBUSxDQUFDUDtJQUN6QztBQUNKO0FBQ0EsU0FBU1gsd0JBQXdCUCxXQUFXLEVBQUVHLGNBQWMsRUFBRUQsZUFBZTtJQUN6RSxNQUFNbUMsVUFBVSxDQUFDO0lBQ2pCLGlGQUFpRjtJQUNqRiwwQkFBMEI7SUFDMUIsS0FBSyxJQUFJQyxhQUFhbkMsZUFBZW9DLGlCQUFpQixDQUFDO1FBQ25ELE1BQU1uQixTQUFTb0IsdUJBQXVCRixVQUFVRyxjQUFjLEVBQUVILFVBQVVJLG1CQUFtQixFQUFFSixVQUFVTixRQUFRLEVBQUVNLFVBQVVLLFdBQVcsRUFBRTNDLGFBQWFFO1FBQ3ZKLElBQUksQ0FBQ21DLE9BQU8sQ0FBQ0MsVUFBVU4sUUFBUSxDQUFDLEVBQUU7WUFDOUJLLE9BQU8sQ0FBQ0MsVUFBVU4sUUFBUSxDQUFDLEdBQUcsQ0FBQztRQUNuQztRQUNBSyxPQUFPLENBQUNDLFVBQVVOLFFBQVEsQ0FBQyxDQUFDTSxVQUFVSyxXQUFXLENBQUMsR0FBRztZQUNqRHZCO1lBQ0FHLFFBQVE7UUFDWjtJQUNKO0lBQ0EsTUFBTXFCLHdCQUF3QmpELG1FQUF3QkE7SUFDdEQsTUFBTXVDLFdBQVdVLHNCQUFzQjNDLFFBQVE7SUFDL0MsTUFBTWlCLFdBQVc7UUFDYm1CO0lBQ0o7SUFDQSwrREFBK0Q7SUFDL0QsSUFBSSxDQUFDM0QsaURBQU1BLENBQUN3RCxTQUFTRyxPQUFPLEVBQUVuQixTQUFTbUIsT0FBTyxHQUFHO1FBQzdDTyxzQkFBc0JuQixRQUFRLENBQUNQO0lBQ25DO0FBQ0o7QUFDQTs7O0NBR0MsR0FBRzs7Ozs7Ozs7Ozs7Q0FXSCxHQUFVLFNBQVMyQixtQkFBbUJoQyxVQUFVLEVBQUVpQyxNQUFNO0lBQ3JEQyxxQkFBcUJsQyxZQUFZaUM7SUFDakMsTUFBTUUsaUJBQWlCcEUsaURBQWNBLENBQUNrRSxRQUFRRztJQUM5QzFELDBEQUFtQkEsQ0FBQ2tDLFFBQVEsQ0FBQyxDQUFDZCxRQUFTO1lBQy9CLEdBQUdBLEtBQUs7WUFDUkssU0FBUztnQkFDTCxHQUFHTCxNQUFNSyxPQUFPO2dCQUNoQixDQUFDSCxXQUFXLEVBQUVtQztZQUNsQjtZQUNBN0IsY0FBYztnQkFDVixHQUFHUixNQUFNUSxZQUFZO2dCQUNyQixDQUFDTixXQUFXLEVBQUU7WUFDbEI7UUFDSjtBQUNSO0FBQ0E7Ozs7Ozs7OztDQVNDLEdBQVUsU0FBU3FDLCtCQUErQnJDLFVBQVU7SUFDekR0QiwwREFBbUJBLENBQUNrQyxRQUFRLENBQUMsQ0FBQ2QsUUFBUztZQUMvQixHQUFHQSxLQUFLO1lBQ1JLLFNBQVM7Z0JBQ0wsR0FBR0wsTUFBTUssT0FBTztnQkFDaEIsQ0FBQ0gsV0FBVyxFQUFFb0M7WUFDbEI7UUFDSjtBQUNSO0FBQ0E7Ozs7Ozs7Q0FPQyxHQUFVLFNBQVNFLG1CQUFtQnRDLFVBQVU7SUFDN0N0QiwwREFBbUJBLENBQUNrQyxRQUFRLENBQUMsQ0FBQ2QsUUFBUztZQUMvQixHQUFHQSxLQUFLO1lBQ1JRLGNBQWM7Z0JBQ1YsR0FBR1IsTUFBTVEsWUFBWTtnQkFDckIsQ0FBQ04sV0FBVyxFQUFFO1lBQ2xCO1FBQ0o7QUFDUjtBQUNBOzs7Ozs7OztDQVFDLEdBQVUsU0FBU3VDLDZCQUE2QkMsU0FBUztJQUN0RDlELDBEQUFtQkEsQ0FBQ2tDLFFBQVEsQ0FBQyxDQUFDZCxRQUFTO1lBQy9CLEdBQUdBLEtBQUs7WUFDUkssU0FBUztnQkFDTCxHQUFHTCxNQUFNSyxPQUFPO2dCQUNoQixDQUFDcUMsVUFBVSxFQUFFQztZQUNqQjtRQUNKO0FBQ1I7QUFDQTs7Ozs7Ozs7Ozs7Ozs7OztDQWdCQyxHQUFVLFNBQVNDLDRCQUE0QkMsYUFBYSxFQUFFVixNQUFNO0lBQ2pFQyxxQkFBcUJTLGVBQWVWO0lBQ3BDLE1BQU1FLGlCQUFpQnBFLGlEQUFjQSxDQUFDa0UsUUFBUUc7SUFDOUMsTUFBTXRDLFFBQVFwQiwwREFBbUJBLENBQUNVLFFBQVE7SUFDMUMsSUFBSVUsTUFBTUssT0FBTyxDQUFDd0MsY0FBYyxFQUFFO1FBQzlCQyxRQUFRQyxLQUFLLENBQUMsQ0FBQyw0QkFBNEIsRUFBRUYsY0FBYywrRkFBK0YsQ0FBQztJQUMvSjtJQUNBakUsMERBQW1CQSxDQUFDa0MsUUFBUSxDQUFDLENBQUNkLFFBQVM7WUFDL0IsR0FBR0EsS0FBSztZQUNSSyxTQUFTO2dCQUNMLEdBQUdMLE1BQU1LLE9BQU87Z0JBQ2hCLENBQUN3QyxjQUFjLEVBQUVSO1lBQ3JCO1FBQ0o7QUFDUjtBQUNPLFNBQVNXLFFBQVF2QyxNQUFNLEVBQUV3QyxhQUFhLFVBQVU7SUFDbkRyRSwwREFBbUJBLENBQUNrQyxRQUFRLENBQUMsQ0FBQ2QsUUFBUztZQUMvQixHQUFHQSxLQUFLO1lBQ1JrRCxpQkFBaUI7bUJBQ1ZsRCxNQUFNa0QsZUFBZTtnQkFDeEI7b0JBQ0lDLFFBQVFGO29CQUNSeEM7Z0JBQ0o7YUFDSDtRQUNMO0FBQ1I7QUFDQTs7Ozs7Ozs7Q0FRQyxHQUFVLFNBQVMyQyxVQUFVbEQsVUFBVTtJQUNwQyxPQUFPLElBQUltRCxRQUFRLENBQUNDO1FBQ2hCLE1BQU1DLFFBQVExRSx5REFBY0EsQ0FBQ3FCO1FBQzdCLFNBQVNzRCxPQUFPeEQsS0FBSztZQUNqQixJQUFJQSxNQUFNWSxNQUFNLElBQUlaLE1BQU1TLE1BQU0sRUFBRTtnQkFDOUIsTUFBTUEsU0FBU3ZDLGlEQUFJQSxDQUFDO29CQUNoQjtvQkFDQTtpQkFDSCxFQUFFOEIsTUFBTVMsTUFBTTtnQkFDZjZDLFFBQVE3QztnQkFDUixJQUFJZ0QsYUFBYTtvQkFDYkE7Z0JBQ0o7WUFDSjtRQUNKO1FBQ0FELE9BQU9ELE1BQU1qRSxRQUFRO1FBQ3JCLE1BQU1tRSxjQUFjRixNQUFNeEQsU0FBUyxDQUFDeUQ7SUFDeEM7QUFDSjtBQUNBLGNBQWMsR0FBVSxTQUFTRSx3QkFBd0J4RCxVQUFVLEVBQUVtQixRQUFRLEVBQUVXLFdBQVc7SUFDdEYsTUFBTTJCLFdBQVc7UUFDYixJQUFJTixRQUFRLENBQUNDO1lBQ1QsTUFBTU0sY0FBYy9FLHlEQUFjQSxDQUFDcUI7WUFDbkMsU0FBU3NELE9BQU94RCxLQUFLO2dCQUNqQixJQUFJQSxNQUFNVywwQkFBMEIsSUFBSVgsTUFBTVMsTUFBTSxFQUFFO29CQUNsRCxNQUFNb0QsdUJBQXVCN0QsTUFBTVMsTUFBTSxDQUFDLHdCQUF3QixJQUFJLENBQUM7b0JBQ3ZFNkMsUUFBUU87b0JBQ1IsSUFBSUosYUFBYTt3QkFDYkE7b0JBQ0o7Z0JBQ0o7WUFDSjtZQUNBRCxPQUFPSSxZQUFZdEUsUUFBUTtZQUMzQixNQUFNbUUsY0FBY0csWUFBWTdELFNBQVMsQ0FBQ3lEO1FBQzlDO0tBQ0g7SUFDRCxJQUFJbkMsWUFBWVcsYUFBYTtRQUN6QjJCLFNBQVM3RCxJQUFJLENBQUMsSUFBSXVELFFBQVEsQ0FBQ0M7WUFDdkIsTUFBTU0sY0FBYzlFLDZEQUFrQkEsQ0FBQ3VDLFVBQVVXO1lBQ2pELFNBQVN3QixPQUFPeEQsS0FBSztnQkFDakIsSUFBSUEsTUFBTVksTUFBTSxJQUFJWixNQUFNUyxNQUFNLEVBQUU7b0JBQzlCLE1BQU1vRCx1QkFBdUI3RCxNQUFNUyxNQUFNLENBQUMsd0JBQXdCLElBQUksQ0FBQztvQkFDdkU2QyxRQUFRTztvQkFDUixJQUFJSixhQUFhO3dCQUNiQTtvQkFDSjtnQkFDSjtZQUNKO1lBQ0FELE9BQU9JLFlBQVl0RSxRQUFRO1lBQzNCLE1BQU1tRSxjQUFjRyxZQUFZN0QsU0FBUyxDQUFDeUQ7UUFDOUM7SUFDSjtJQUNBLE9BQU9ILFFBQVFTLEdBQUcsQ0FBQ0g7QUFDdkI7QUFDQTs7Ozs7Ozs7Q0FRQyxHQUFVLFNBQVNJLGNBQWM1QixNQUFNLEVBQUU2QixjQUFjLEVBQUVDLGNBQWM7SUFDcEVDLGtCQUFrQi9CLFFBQVE2QixnQkFBZ0JDO0lBQzFDLE1BQU14RCxTQUFTMEQsWUFBWWhDLFFBQVE2QjtJQUNuQ0ksNkJBQTZCakMsUUFBUTFCLFFBQVF3RDtJQUM3QyxPQUFPeEQ7QUFDWDtBQUNBOzs7Q0FHQyxHQUFHOzs7Ozs7Ozs7Ozs7Q0FZSCxHQUFHLFNBQVNvQix1QkFBdUJDLGNBQWMsRUFBRUMsbUJBQW1CLEVBQUVWLFFBQVEsRUFBRVcsV0FBVyxFQUFFM0MsV0FBVyxFQUFFRSxlQUFlO0lBQ3hILE1BQU1zRCxnQkFBZ0J3Qix1QkFBdUJyQztJQUM3QyxNQUFNc0Msd0JBQXdCakYsWUFBWWdCLE9BQU8sQ0FBQ3dDLGNBQWM7SUFDaEUsTUFBTTBCLHFCQUFxQkQsd0JBQXdCekIsZ0JBQWdCZDtJQUNuRSxNQUFNbUIsa0JBQWtCc0IsbUJBQW1CbkYsYUFBYUU7SUFDeEQsTUFBTWtGLG1CQUFtQkMsZ0JBQWdCNUMsZ0JBQWdCb0I7SUFDekQsTUFBTXlCLGlCQUFpQkYsa0JBQWtCRyxnQkFBZ0IsQ0FBQ3ZELFNBQVMsRUFBRXdELFdBQVcsQ0FBQzdDLFlBQVksSUFBSSxDQUFDO0lBQ2xHLE1BQU04QyxrQkFBa0JKLGdCQUFnQkgsb0JBQW9CckI7SUFDNUQsTUFBTTZCLGlCQUFpQkMsYUFBYTtRQUNoQ0Y7UUFDQUg7S0FDSDtJQUNELE1BQU14QyxTQUFTbUMseUJBQXlCakYsWUFBWWdCLE9BQU8sQ0FBQzBCLG9CQUFvQjtJQUNoRm1DLGtCQUFrQi9CLFFBQVE0QyxnQkFBZ0JSO0lBQzFDLE1BQU05RCxTQUFTMEQsWUFBWWhDLFFBQVE0QztJQUNuQ1gsNkJBQTZCakMsUUFBUTFCLFFBQVE4RDtJQUM3QyxPQUFPOUQsT0FBT21FLGNBQWM7SUFDNUIsT0FBT25FO0FBQ1g7QUFDQSxTQUFTZ0IsMEJBQTBCcEMsV0FBVyxFQUFFRSxlQUFlO0lBQzNELElBQUkwRixTQUFTQyw4QkFBOEJwSCxpREFBS0EsQ0FBQ3VCLFlBQVlnQixPQUFPO0lBQ3BFLE1BQU04RSxvQkFBb0I7V0FDbkI5RixZQUFZNkQsZUFBZSxDQUFDOUIsR0FBRyxDQUFDLENBQUNnRSxJQUFJO2dCQUNoQ0EsRUFBRTNFLE1BQU07Z0JBQ1IyRSxFQUFFakMsTUFBTTthQUNYO1FBQ0w7WUFDSTVELGdCQUFnQmtCLE1BQU07WUFDdEI7U0FDSDtLQUNKO0lBQ0QsS0FBSyxJQUFJLENBQUNBLFFBQVEwQyxPQUFPLElBQUlnQyxrQkFBa0I7UUFDM0NGLFNBQVNELGFBQWE7WUFDbEJDO1lBQ0FJLDJCQUEyQjVFLFFBQVEwQztTQUN0QztJQUNMO0lBQ0EsT0FBTzhCO0FBQ1g7QUFDQSxTQUFTQyw4QkFBOEIvQyxNQUFNO0lBQ3pDLElBQUlBLE9BQU9tRCxjQUFjLENBQUMsYUFBYTtRQUNuQyxPQUFPO1lBQ0gsR0FBR25ELE1BQU07WUFDVG9ELFFBQVFwRCxPQUFPcUQsUUFBUTtZQUN2QkMsU0FBUztRQUNiO0lBQ0osT0FBTyxJQUFJQyxpQkFBaUJ2RCxTQUFTO1FBQ2pDLE9BQU9oQyxPQUFPQyxJQUFJLENBQUMrQixRQUFRbkUsTUFBTSxDQUFDLENBQUMySCxLQUFLQztZQUNwQ0QsR0FBRyxDQUFDQyxJQUFJLEdBQUdWLDhCQUE4Qi9DLE1BQU0sQ0FBQ3lELElBQUk7WUFDcEQsT0FBT0Q7UUFDWCxHQUFHLENBQUM7SUFDUixPQUFPO1FBQ0gsK0ZBQStGO1FBQy9GLE9BQU8sQ0FBQztJQUNaO0FBQ0o7QUFDQSxTQUFTTiwyQkFBMkI1RSxNQUFNLEVBQUUwQyxNQUFNO0lBQzlDLElBQUl1QyxpQkFBaUJqRixTQUFTO1FBQzFCLE9BQU9OLE9BQU9DLElBQUksQ0FBQ0ssUUFBUXpDLE1BQU0sQ0FBQyxDQUFDMkgsS0FBS0M7WUFDcENELEdBQUcsQ0FBQ0MsSUFBSSxHQUFHUCwyQkFBMkI1RSxNQUFNLENBQUNtRixJQUFJLEVBQUV6QztZQUNuRCxPQUFPd0M7UUFDWCxHQUFHLENBQUM7SUFDUixPQUFPO1FBQ0gsT0FBTztZQUNISixRQUFROUU7WUFDUmdGLFNBQVN0QztRQUNiO0lBQ0o7QUFDSjtBQUNBLFNBQVNuQyx3QkFBd0IzQixXQUFXLEVBQUVFLGVBQWU7SUFDekQsTUFBTXNHLGFBQWFiLGFBQWFSLG1CQUFtQm5GLGFBQWFFO0lBQ2hFLE1BQU11RyxzQkFBc0IzRixPQUFPQyxJQUFJLENBQUN5RixZQUFZN0gsTUFBTSxDQUFDLENBQUMySCxLQUFLQztRQUM3RCxJQUFJQyxVQUFVLENBQUNELElBQUksRUFBRWhCLGdCQUFnQjtZQUNqQ2UsR0FBRyxDQUFDQyxJQUFJLEdBQUdDLFVBQVUsQ0FBQ0QsSUFBSSxFQUFFaEI7UUFDaEM7UUFDQSxPQUFPZTtJQUNYLEdBQUcsQ0FBQztJQUNKSSxnQ0FBZ0NEO0lBQ2hDLE1BQU0vRSxjQUFjWixPQUFPQyxJQUFJLENBQUMwRixxQkFBcUI5SCxNQUFNLENBQUMsQ0FBQzJILEtBQUtDO1FBQzlERCxNQUFNO1lBQ0YsR0FBR0EsR0FBRztZQUNOLEdBQUdHLG1CQUFtQixDQUFDRixJQUFJO1FBQy9CO1FBQ0EsT0FBT0Q7SUFDWCxHQUFHLENBQUM7SUFDSixPQUFPNUU7QUFDWDtBQUNBLFNBQVNnRixnQ0FBZ0NELG1CQUFtQjtJQUN4RCxLQUFLLElBQUksQ0FBQzVGLFlBQVk4RixpQkFBaUIsSUFBSTdGLE9BQU9nQixPQUFPLENBQUMyRSxxQkFBcUI7UUFDM0UsS0FBSyxJQUFJLENBQUN6RSxVQUFVWixPQUFPLElBQUlOLE9BQU9nQixPQUFPLENBQUM2RSxrQkFBa0I7WUFDNURDLDRCQUE0QnhGLFFBQVFQLFlBQVltQjtRQUNwRDtJQUNKO0FBQ0o7QUFDQSxTQUFTNEUsNEJBQTRCeEYsTUFBTSxFQUFFUCxVQUFVLEVBQUVtQixRQUFRO0lBQzdELE1BQU02RSxVQUFVLEdBQUdoRyxXQUFXLGdCQUFnQixFQUFFbUIsVUFBVTtJQUMxRCxNQUFNOEUsY0FBYyxDQUFDLHVCQUF1QixFQUFFRCxRQUFRLENBQUMsQ0FBQztJQUN4RCxNQUFNRSxjQUFjakcsT0FBT0MsSUFBSSxDQUFDSyxRQUFRNEYsTUFBTSxDQUFDLENBQUNDLElBQUksQ0FBQztZQUM3QztZQUNBO1lBQ0E7WUFDQTtTQUNILENBQUNDLFFBQVEsQ0FBQ0Q7SUFDZixJQUFJRixZQUFZSSxNQUFNLEVBQUU7UUFDcEJDLFNBQVNQLFNBQVNDLGNBQWMsQ0FBQyx5QkFBeUIsRUFBRUMsWUFBWU0sSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQzNGO0lBQ0EsSUFBSWpHLE9BQU9rRyxHQUFHLEVBQUU7UUFDWixJQUFJLENBQUNDLE1BQU14SSxPQUFPLENBQUNxQyxPQUFPa0csR0FBRyxLQUFLLENBQUNsRyxPQUFPa0csR0FBRyxDQUFDRSxLQUFLLENBQUMsQ0FBQ0MsSUFBSSxPQUFPQSxNQUFNLFdBQVc7WUFDN0VMLFNBQVNQLFNBQVNDLGNBQWMsQ0FBQyw2REFBNkQsQ0FBQztRQUNuRztJQUNKO0lBQ0EsSUFBSTFGLE9BQU9zRyxNQUFNLEVBQUU7UUFDZixJQUFJLENBQUNILE1BQU14SSxPQUFPLENBQUNxQyxPQUFPc0csTUFBTSxLQUFLLENBQUN0RyxPQUFPc0csTUFBTSxDQUFDRixLQUFLLENBQUMsQ0FBQ0MsSUFBSSxPQUFPQSxNQUFNLFdBQVc7WUFDbkZMLFNBQVNQLFNBQVNDLGNBQWMsQ0FBQyxnRUFBZ0UsQ0FBQztRQUN0RztJQUNKO0lBQ0EsSUFBSTFGLE9BQU91RyxLQUFLLEVBQUU7UUFDZCxJQUFJLENBQUNKLE1BQU14SSxPQUFPLENBQUNxQyxPQUFPdUcsS0FBSyxLQUFLLENBQUN2RyxPQUFPdUcsS0FBSyxDQUFDSCxLQUFLLENBQUMsQ0FBQ0MsSUFBSSxPQUFPQSxNQUFNLFdBQVc7WUFDakZMLFNBQVNQLFNBQVNDLGNBQWMsQ0FBQywrREFBK0QsQ0FBQztRQUNyRztJQUNKO0lBQ0EsSUFBSTFGLE9BQU9vRSxTQUFTLEVBQUU7UUFDbEIsSUFBSSxDQUFDYSxpQkFBaUJqRixPQUFPb0UsU0FBUyxHQUFHO1lBQ3JDNEIsU0FBU1AsU0FBU0MsY0FBYyxDQUFDLHFFQUFxRSxDQUFDO1FBQzNHO0lBQ0o7QUFDSjtBQUNBLFNBQVMzQixtQkFBbUJuRixXQUFXLEVBQUVFLGVBQWU7SUFDcEQsT0FBTztXQUNBRixZQUFZNkQsZUFBZSxDQUFDOUIsR0FBRyxDQUFDLENBQUNnRSxJQUFJQSxFQUFFM0UsTUFBTTtRQUNoRGxCLGdCQUFnQmtCLE1BQU07S0FDekI7QUFDTDtBQUNBOzs7O0NBSUMsR0FBRyxTQUFTMkIscUJBQXFCbEMsVUFBVSxFQUFFaUMsTUFBTSxFQUFFK0QsVUFBVSxFQUFFO0lBQzlELE1BQU1lLGdCQUFnQixDQUFDLHVGQUF1RixDQUFDO0lBQy9HLEtBQUssTUFBTXJCLE9BQU96RixPQUFPQyxJQUFJLENBQUMrQixRQUFRa0UsTUFBTSxDQUFDLENBQUNDLElBQUksQ0FBQ0EsRUFBRVksVUFBVSxDQUFDLE1BQU07UUFDbEUsTUFBTUMsY0FBY2pCLFVBQVdBLENBQUFBLFdBQVcsR0FBRSxJQUFLTjtRQUNqRCxNQUFNd0IsYUFBYWpGLE1BQU0sQ0FBQ3lELElBQUk7UUFDOUIsSUFBSXVCLGdCQUFnQixzQkFBc0I7WUFDdENyRSxRQUFRQyxLQUFLLENBQUMsR0FBRzdDLFdBQVcsa0hBQWtILEVBQUUrRyxlQUFlO1FBQ25LO1FBQ0EsSUFBSUUsZ0JBQWdCLHlCQUF5QjtZQUN6Q3JFLFFBQVFDLEtBQUssQ0FBQyxHQUFHN0MsV0FBVyx3SEFBd0gsRUFBRStHLGVBQWU7UUFDeks7UUFDQSxJQUFJLENBQUN2QixpQkFBaUIwQixhQUFhO1lBQy9CdEUsUUFBUUMsS0FBSyxDQUFDLEdBQUc3QyxXQUFXLDJDQUEyQyxFQUFFaUgsWUFBWSxHQUFHLEVBQUVGLGVBQWU7WUFDekc7UUFDSjtRQUNBLElBQUksQ0FBQ0csV0FBVzlCLGNBQWMsQ0FBQyxhQUFhO1lBQ3hDLGlDQUFpQztZQUNqQ2xELHFCQUFxQmxDLFlBQVlrSCxZQUFZRDtRQUNqRDtRQUNBLE1BQU1FLFdBQVdELFdBQVdFLFNBQVM7UUFDckMsSUFBSUMsZ0JBQWdCRixXQUFXO1lBQzNCakYscUJBQXFCbEMsWUFBWW1ILFVBQVVGLGNBQWM7UUFDN0Q7UUFDQSxJQUFJQyxXQUFXSSxXQUFXLEVBQUU7WUFDeEIsS0FBSyxJQUFJOUksYUFBYTBJLFdBQVdJLFdBQVcsQ0FBQztnQkFDekMsSUFBSSxPQUFPOUksY0FBYyxZQUFZO29CQUNqQ29FLFFBQVFDLEtBQUssQ0FBQyxHQUFHN0MsV0FBVyxnQ0FBZ0MsRUFBRWlILFlBQVksRUFBRSxFQUFFRixjQUFjLENBQUMsQ0FBQyxHQUFHLENBQUMsOEVBQThFLENBQUMsR0FBRyxDQUFDLHVDQUF1QyxFQUFFdkksVUFBVSxDQUFDLENBQUM7Z0JBQzlPO1lBQ0o7UUFDSjtRQUNBLE1BQU0rSSxZQUFZTCxXQUFXTSxLQUFLO1FBQ2xDLElBQUlELGFBQWEsQ0FBQ3RILE9BQU93SCxNQUFNLENBQUN4SiwyQ0FBSUEsRUFBRW9JLFFBQVEsQ0FBQ2tCLFlBQVk7WUFDdkQzRSxRQUFRQyxLQUFLLENBQUMsR0FBRzdDLFdBQVcsMkJBQTJCLEVBQUVpSCxZQUFZLEVBQUUsRUFBRUYsY0FBYyxDQUFDLENBQUMsR0FBRyxDQUFDLG9EQUFvRCxFQUFFOUcsT0FBT3dILE1BQU0sQ0FBQ3hKLDJDQUFJQSxFQUFFdUksSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDLEdBQUcsQ0FBQyxVQUFVLEVBQUVlLFVBQVUsQ0FBQyxDQUFDO1FBQ3JOO1FBQ0EsSUFBSXRILE9BQU9DLElBQUksQ0FBQ2dILFlBQVlQLEtBQUssQ0FBQyxDQUFDUCxJQUFJO2dCQUMvQjtnQkFDQTtnQkFDQTtnQkFDQTthQUNILENBQUNDLFFBQVEsQ0FBQ0QsT0FBTyxDQUFDSixRQUFRSyxRQUFRLENBQUMsZUFBZTtZQUNuRHpELFFBQVFDLEtBQUssQ0FBQyxHQUFHN0MsV0FBVywyQ0FBMkMsRUFBRWlILFlBQVksR0FBRyxFQUFFRixjQUFjLENBQUMsQ0FBQyxHQUFHLENBQUMsdUVBQXVFLENBQUMsR0FBRyxDQUFDLFNBQVMsRUFBRVcsS0FBS0MsU0FBUyxDQUFDVCxhQUFhO1FBQ3JPO1FBQ0EsSUFBSUMsWUFBWUksYUFBYSxDQUFDO1lBQzFCdEosMkNBQUlBLENBQUN5SSxLQUFLO1lBQ1Z6SSwyQ0FBSUEsQ0FBQ2dDLE1BQU07U0FDZCxDQUFDb0csUUFBUSxDQUFDa0IsWUFBWTtZQUNuQjNFLFFBQVFDLEtBQUssQ0FBQyxHQUFHN0MsV0FBVywyQ0FBMkMsRUFBRWlILFlBQVksR0FBRyxFQUFFRixjQUFjLENBQUMsQ0FBQyxHQUFHLENBQUMsdUdBQXVHLENBQUMsR0FBRyxDQUFDLFNBQVMsRUFBRVcsS0FBS0MsU0FBUyxDQUFDSixZQUFZO1FBQ3BRO0lBQ0o7QUFDSjtBQUNBLFNBQVMvRyxtQkFBbUJSLFVBQVUsRUFBRWIsV0FBVyxFQUFFRSxlQUFlO0lBQ2hFLE1BQU00QyxTQUFTOUMsWUFBWWdCLE9BQU8sQ0FBQ0gsV0FBVztJQUM5QyxNQUFNNEgsY0FBY3BELGdCQUFnQnhFLFlBQVlzRSxtQkFBbUJuRixhQUFhRTtJQUNoRjJFLGtCQUFrQi9CLFFBQVEyRixhQUFhNUg7SUFDdkMsTUFBTU8sU0FBUzBELFlBQVloQyxRQUFRMkY7SUFDbkMxRCw2QkFBNkJqQyxRQUFRMUIsUUFBUVA7SUFDN0MsT0FBT08sT0FBT21FLGNBQWM7SUFDNUIsT0FBT25FO0FBQ1g7QUFDQSxTQUFTSSxpQ0FBaUNYLFVBQVUsRUFBRWIsV0FBVyxFQUFFRSxlQUFlO0lBQzlFLE1BQU11SSxjQUFjcEQsZ0JBQWdCeEUsWUFBWXNFLG1CQUFtQm5GLGFBQWFFO0lBQ2hGLE1BQU1rQixTQUFTMEQsWUFBWTdCLHNCQUFzQndGO0lBQ2pEMUQsNkJBQTZCOUIsc0JBQXNCN0IsUUFBUVA7SUFDM0QsT0FBT08sT0FBT21FLGNBQWM7SUFDNUIsT0FBT25FO0FBQ1g7QUFDQSxTQUFTaUUsZ0JBQWdCeEUsVUFBVSxFQUFFMkYsVUFBVTtJQUMzQyxNQUFNa0Msc0JBQXNCbEMsV0FBV3pFLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQ2xCLFdBQVcsRUFBRWtGLENBQUMsRUFBRSxHQUFHQSxHQUFHaUIsTUFBTSxDQUFDLENBQUNqQixJQUFJLENBQUMsQ0FBQ0E7SUFDbkYsT0FBT0osYUFBYStDO0FBQ3hCO0FBQ0EsU0FBUy9DLGFBQWF0RCxPQUFPO0lBQ3pCLE1BQU1zRyxlQUFlaEssaURBQU1BLENBQUNDLDZDQUFjQTtJQUMxQyxPQUFPK0osYUFBYSxDQUFDLEdBQUd0RztBQUM1QjtBQUNBOzs7OztDQUtDLEdBQUcsU0FBU3dDLGtCQUFrQi9CLE1BQU0sRUFBRTFCLE1BQU0sRUFBRXlGLFVBQVUsRUFBRTtJQUN2RCxvQ0FBb0M7SUFDcEMsS0FBSyxNQUFNTixPQUFPekYsT0FBT0MsSUFBSSxDQUFDSyxRQUFRO1FBQ2xDLE1BQU13SCxRQUFReEgsTUFBTSxDQUFDbUYsSUFBSTtRQUN6QixNQUFNdUIsY0FBY2pCLFVBQVUsTUFBTU47UUFDcEMsTUFBTXdCLGFBQWFqRixNQUFNLENBQUN5RCxJQUFJO1FBQzlCLElBQUksQ0FBQ3pELE9BQU9tRCxjQUFjLENBQUNNLE1BQU07WUFDN0IsSUFBSSxDQUFFQSxDQUFBQSxRQUFRLG9CQUFvQk0sWUFBWSxFQUFDLEdBQUk7Z0JBQy9DTyxTQUFTVSxhQUFhLENBQUMsb0JBQW9CLEVBQUVBLFlBQVkscUJBQXFCLENBQUM7WUFDbkY7WUFDQTtRQUNKO1FBQ0FlLHdCQUF3QmQsWUFBWWEsT0FBT2Q7SUFDL0M7QUFDSjtBQUNBLFNBQVNlLHdCQUF3QmQsVUFBVSxFQUFFYSxLQUFLLEVBQUUvQixPQUFPO0lBQ3ZEaUMsVUFBVWpDLFNBQVNrQixXQUFXTSxLQUFLLEVBQUVPO0lBQ3JDLElBQUl2QyxpQkFBaUJ1QyxRQUFRO1FBQ3pCLElBQUliLFdBQVdNLEtBQUssS0FBS3ZKLDJDQUFJQSxDQUFDZ0MsTUFBTSxFQUFFO1lBQ2xDLDhCQUE4QjtZQUM5QmlJLGdDQUFnQ2hCLFlBQVlhLE9BQU8vQjtRQUN2RCxPQUFPLElBQUksQ0FBRWtCLENBQUFBLFdBQVc5QixjQUFjLENBQUMsZUFBZThCLFdBQVc5QixjQUFjLENBQUMsUUFBTyxHQUFJO1lBQ3ZGLG1DQUFtQztZQUNuQ3BCLGtCQUFrQmtELFlBQVlhLE9BQU8vQjtRQUN6QztJQUNKLE9BQU87UUFDSCxJQUFJa0IsV0FBV00sS0FBSyxLQUFLdkosMkNBQUlBLENBQUN5SSxLQUFLLEVBQUU7WUFDakN5Qix1QkFBdUJqQixZQUFZYSxPQUFPL0I7UUFDOUM7SUFDSjtBQUNKO0FBQ0EsU0FBU2tDLGdDQUFnQ0Usb0JBQW9CLEVBQUU3SCxNQUFNLEVBQUV5RixPQUFPO0lBQzFFLElBQUlvQyxxQkFBcUJoQixTQUFTLEVBQUU7UUFDaEMsS0FBSyxNQUFNMUIsT0FBT3pGLE9BQU9DLElBQUksQ0FBQ0ssUUFBUTtZQUNsQyxNQUFNd0gsUUFBUXhILE1BQU0sQ0FBQ21GLElBQUk7WUFDekJzQyx3QkFBd0JJLHFCQUFxQmhCLFNBQVMsRUFBRVcsT0FBTyxHQUFHL0IsUUFBUSxDQUFDLEVBQUVOLEtBQUs7UUFDdEY7SUFDSjtBQUNKO0FBQ0EsU0FBU3lDLHVCQUF1QkUsV0FBVyxFQUFFTixLQUFLLEVBQUUvQixPQUFPO0lBQ3ZELE1BQU1zQyxtQkFBbUJMLFVBQVVqQyxTQUFTL0gsMkNBQUlBLENBQUN5SSxLQUFLLEVBQUVxQjtJQUN4RCxJQUFJLENBQUNPLGtCQUFrQjtRQUNuQjtJQUNKO0lBQ0EsNEVBQTRFO0lBQzVFLElBQUlqQixnQkFBZ0JnQixZQUFZakIsU0FBUyxHQUFHO1FBQ3hDLElBQUksSUFBSW1CLElBQUksR0FBR0EsSUFBSVIsTUFBTXpCLE1BQU0sRUFBRWlDLElBQUk7WUFDakNQLHdCQUF3QkssWUFBWWpCLFNBQVMsRUFBRVcsS0FBSyxDQUFDUSxFQUFFLEVBQUUsR0FBR3ZDLFFBQVEsQ0FBQyxFQUFFdUMsRUFBRSxDQUFDLENBQUM7UUFDL0U7SUFDSjtJQUNBLElBQUksSUFBSUEsSUFBSSxHQUFHQSxJQUFJUixNQUFNekIsTUFBTSxFQUFFaUMsSUFBSTtRQUNqQ04sVUFBVSxHQUFHakMsUUFBUSxDQUFDLEVBQUV1QyxFQUFFLENBQUMsQ0FBQyxFQUFFRixZQUFZakIsU0FBUyxFQUFFSSxPQUFPTyxLQUFLLENBQUNRLEVBQUU7SUFDeEU7QUFDSjtBQUNBOzs7O0NBSUMsR0FBRyxTQUFTckUsNkJBQTZCakMsTUFBTSxFQUFFMUIsTUFBTSxFQUFFeUYsVUFBVSxFQUFFO0lBQ2xFLHNGQUFzRjtJQUN0RixJQUFJL0QsUUFBUTtRQUNSLElBQUkxQixXQUFXMEIsT0FBT3FELFFBQVEsRUFBRTtZQUM1QmtELGNBQWN4QyxTQUFTL0QsT0FBT3FGLFdBQVcsRUFBRS9HO1FBQy9DO1FBQ0EsSUFBSWlGLGlCQUFpQmpGLFNBQVM7WUFDMUIsS0FBSyxNQUFNbUYsT0FBT3pGLE9BQU9DLElBQUksQ0FBQ0ssUUFBUTtnQkFDbEMsTUFBTXdILFFBQVF4SCxNQUFNLENBQUNtRixJQUFJO2dCQUN6QixNQUFNdUIsY0FBY2pCLFVBQVUsTUFBTU47Z0JBQ3BDLE1BQU13QixhQUFhakYsTUFBTSxDQUFDeUQsSUFBSTtnQkFDOUIsSUFBSXpELE9BQU91RixLQUFLLEtBQUt2SiwyQ0FBSUEsQ0FBQ2dDLE1BQU0sSUFBSWdDLE9BQU9tRixTQUFTLEVBQUU7b0JBQ2xEbEQsNkJBQTZCakMsT0FBT21GLFNBQVMsRUFBRVcsT0FBT2Q7Z0JBQzFELE9BQU87b0JBQ0gvQyw2QkFBNkJnRCxZQUFZYSxPQUFPZDtnQkFDcEQ7WUFDSjtRQUNKLE9BQU8sSUFBSVAsTUFBTXhJLE9BQU8sQ0FBQ3FDLFdBQVcwQixPQUFPbUYsU0FBUyxFQUFFO1lBQ2xELElBQUksSUFBSW1CLElBQUksR0FBR0EsSUFBSWhJLE9BQU8rRixNQUFNLEVBQUVpQyxJQUFJO2dCQUNsQ3JFLDZCQUE2QmpDLE9BQU9tRixTQUFTLEVBQUU3RyxNQUFNLENBQUNnSSxFQUFFLEVBQUUsR0FBR3ZDLFFBQVEsQ0FBQyxFQUFFdUMsRUFBRSxDQUFDLENBQUM7WUFDaEY7UUFDSjtJQUNKO0FBQ0o7QUFDQTs7O0NBR0MsR0FBRyxTQUFTTixVQUFVakMsT0FBTyxFQUFFd0IsS0FBSyxFQUFFTyxLQUFLO0lBQ3hDLElBQUlQLE9BQU87UUFDUCxzRUFBc0U7UUFDdEUsTUFBTWhKLFlBQVk7WUFDZGtJLE9BQU94SSxtRUFBT0E7WUFDZHVLLFNBQVN0SyxxRUFBU0E7WUFDbEJ1SyxhQUFhdEssa0VBQU1BO1lBQ25CdUssUUFBUXRLLG9FQUFRQTtZQUNoQjRCLFFBQVEzQixvRUFBUUE7WUFDaEJzSyxRQUFRckssb0VBQVFBO1lBQ2hCc0ssTUFBTXpLLGtFQUFNQTtZQUNaMEsseUJBQXlCMUssa0VBQU1BO1lBQy9CMkssMkJBQTJCM0ssa0VBQU1BO1FBQ3JDO1FBQ0EsT0FBT29LLGNBQWN4QyxTQUFTO1lBQzFCeEgsU0FBUyxDQUFDZ0osTUFBTTtTQUNuQixFQUFFTztJQUNQO0lBQ0EsT0FBTztBQUNYO0FBQ0E7OztDQUdDLEdBQUcsc0VBQXNFO0FBQzFFLFNBQVNTLGNBQWN4QyxPQUFPLEVBQUVnRCxVQUFVLEVBQUVqQixLQUFLO0lBQzdDLElBQUlrQixjQUFjO0lBQ2xCLElBQUlELFlBQVk7UUFDWixJQUFJO1lBQ0EsS0FBSyxJQUFJeEssYUFBYXdLLFdBQVc7Z0JBQzdCLE1BQU1FLGtCQUFrQjFLLFVBQVV1SjtnQkFDbEMsSUFBSSxPQUFPbUIsb0JBQW9CLFVBQVU7b0JBQ3JDLE1BQU1DLFVBQVUsT0FBT3BCLFVBQVUsV0FBVyxDQUFDLDBCQUEwQixFQUFFL0IsUUFBUSxFQUFFLEVBQUVrRCxpQkFBaUIsR0FBRyxDQUFDLDRCQUE0QixFQUFFbkIsTUFBTSxLQUFLLEVBQUUvQixRQUFRLEVBQUUsRUFBRWtELGlCQUFpQjtvQkFDbEwzQyxTQUFTUCxTQUFTbUQ7b0JBQ2xCRixjQUFjO2dCQUNsQjtZQUNKO1FBQ0osRUFBRSxPQUFPRyxHQUFHO1lBQ1J4RyxRQUFRQyxLQUFLLENBQUMsQ0FBQywrQkFBK0IsRUFBRW1ELFFBQVEsd0JBQXdCLEVBQUVvRCxHQUFHO1FBQ3pGO0lBQ0o7SUFDQSxPQUFPSDtBQUNYO0FBQ0EsOERBQThEO0FBQzlELE1BQU1oRixjQUFjLENBQUNoQyxRQUFRMkY7SUFDekIsTUFBTXJILFNBQVMzQyxpREFBS0EsQ0FBQ2dLO0lBQ3JCLElBQUksQ0FBQzNGLFFBQVE7UUFDVCxPQUFPMUI7SUFDWDtJQUNBLEtBQUssTUFBTW1GLE9BQU96RixPQUFPQyxJQUFJLENBQUMrQixRQUFRO1FBQ2xDLE1BQU1vSCxhQUFhOUksTUFBTSxDQUFDbUYsSUFBSTtRQUM5QixNQUFNd0IsYUFBYWpGLE1BQU0sQ0FBQ3lELElBQUk7UUFDOUIsbUVBQW1FO1FBQ25FLHFFQUFxRTtRQUNyRSxtRUFBbUU7UUFDbkUsc0VBQXNFO1FBQ3RFLHdCQUF3QjtRQUN4QixJQUFJd0IsY0FBZUEsQ0FBQUEsV0FBVzlCLGNBQWMsQ0FBQyxZQUFZOEIsV0FBVzlCLGNBQWMsQ0FBQyxXQUFVLEdBQUk7WUFDN0YsaUVBQWlFO1lBQ2pFLG9DQUFvQztZQUNwQyxJQUFJLENBQUM3RSxPQUFPNkUsY0FBYyxDQUFDTSxNQUFNO2dCQUM3Qm5GLE1BQU0sQ0FBQ21GLElBQUksR0FBR3dCLFVBQVUsQ0FBQyxXQUFXO1lBQ3hDO1lBQ0EsMkZBQTJGO1lBQzNGLE1BQU1DLFdBQVdELFdBQVdFLFNBQVM7WUFDckMsSUFBSWlDLGNBQWNoQyxnQkFBZ0JGLFdBQVc7Z0JBQ3pDLElBQUlELFdBQVdNLEtBQUssS0FBS3ZKLDJDQUFJQSxDQUFDeUksS0FBSyxJQUFJQSxNQUFNeEksT0FBTyxDQUFDbUwsYUFBYTtvQkFDOUQsTUFBTUMscUJBQXFCRCxXQUFXbkksR0FBRyxDQUFDLENBQUNxSSxPQUFPdEYsWUFBWWtELFVBQVVvQztvQkFDeEVoSixNQUFNLENBQUNtRixJQUFJLEdBQUc0RDtnQkFDbEIsT0FBTyxJQUFJcEMsV0FBV00sS0FBSyxLQUFLdkosMkNBQUlBLENBQUNnQyxNQUFNLEVBQUU7b0JBQ3pDLEtBQUssSUFBSXVKLGFBQWF2SixPQUFPQyxJQUFJLENBQUNtSixZQUFZO3dCQUMxQ0EsVUFBVSxDQUFDRyxVQUFVLEdBQUd2RixZQUFZa0QsVUFBVWtDLFVBQVUsQ0FBQ0csVUFBVTtvQkFDdkU7Z0JBQ0o7WUFDSjtRQUNKLE9BQU8sSUFBSWhFLGlCQUFpQjBCLGFBQWE7WUFDckMsdUVBQXVFO1lBQ3ZFLHlGQUF5RjtZQUN6Rix3RUFBd0U7WUFDeEUsTUFBTXVDLHFCQUFxQkosY0FBYyxDQUFDO1lBQzFDLHVGQUF1RjtZQUN2RixJQUFJN0QsaUJBQWlCaUUscUJBQXFCO2dCQUN0Q2xKLE1BQU0sQ0FBQ21GLElBQUksR0FBR3pCLFlBQVlpRCxZQUFZdUM7WUFDMUM7UUFDSjtJQUNKO0lBQ0EsT0FBT2xKO0FBQ1g7QUFDQSxTQUFTOEcsZ0JBQWdCcUMsY0FBYztJQUNuQyxPQUFPLENBQUMsQ0FBQ0Esa0JBQWtCekosT0FBT0MsSUFBSSxDQUFDd0osZ0JBQWdCdkQsTUFBTSxDQUFDLENBQUNpRCxJQUFJLENBQUM7WUFDNUQ7WUFDQTtTQUNILENBQUMvQyxRQUFRLENBQUMrQyxJQUFJOUMsTUFBTSxHQUFHO0FBQ2hDO0FBQ0EsU0FBU2QsaUJBQWlCdUMsS0FBSztJQUMzQixPQUFPLE9BQU9BLFVBQVUsWUFBWSxDQUFDckIsTUFBTXhJLE9BQU8sQ0FBQzZKLFVBQVVBLFVBQVU7QUFDM0U7QUFDQSxxR0FBcUcsR0FBRyxJQUFJNEIsOEJBQThCLElBQUlDO0FBQzlJLFNBQVNyRCxTQUFTUCxPQUFPLEVBQUVtRCxPQUFPO0lBQzlCLE1BQU16RCxNQUFNLEdBQUdNLFFBQVEsR0FBRyxFQUFFbUQsU0FBUztJQUNyQyxnSEFBZ0g7SUFDaEgsSUFBSSxDQUFDUSw2QkFBNkI7UUFDOUJBLDhCQUE4QixJQUFJQztJQUN0QztJQUNBLElBQUksQ0FBQ0QsNEJBQTRCRSxHQUFHLENBQUNuRSxNQUFNO1FBQ3ZDOUMsUUFBUUMsS0FBSyxDQUFDc0c7UUFDZFEsNEJBQTRCbEQsR0FBRyxDQUFDZjtJQUNwQztBQUNKO0FBQ0E7Ozs7O0NBS0MsR0FBVSxTQUFTb0Usa0JBQWtCOUQsT0FBTztJQUN6QyxJQUFJQSxTQUFTO1FBQ1QyRCw0QkFBNEJJLE9BQU8sQ0FBQyxDQUFDckU7WUFDakMsSUFBSUEsSUFBSXNCLFVBQVUsQ0FBQ2hCLFVBQVU7Z0JBQ3pCMkQsNEJBQTRCSyxNQUFNLENBQUN0RTtZQUN2QztRQUNKO0lBQ0osT0FBTztRQUNIaUUsNEJBQTRCTSxLQUFLO0lBQ3JDO0FBQ0o7QUFDQTs7Ozs7OztDQU9DLEdBQVUsU0FBU0M7SUFDaEJqTCxvQkFBb0I4SyxPQUFPLENBQUMsQ0FBQ3hHLGNBQWNBO0lBQzNDdEUsb0JBQW9CcUgsTUFBTSxHQUFHO0lBQzdCM0c7QUFDSjtBQUNBOzs7Q0FHQyxHQUFHLFNBQVN3RSx1QkFBdUJyQyxXQUFXO0lBQzNDLE1BQU0sQ0FBQ2EsY0FBYyxHQUFHYixZQUFZcUksS0FBSyxDQUFDO0lBQzFDLE9BQU94SDtBQUNYO0FBQ0E7OztDQUdDLEdBQUcsTUFBTUYsNkJBQTZCO0lBQ25DLHlCQUF5QjtRQUNyQjJILGNBQWM7UUFDZDVDLE9BQU92SiwyQ0FBSUEsQ0FBQ2dDLE1BQU07UUFDbEJxRixVQUFVLENBQUM7UUFDWGdDLGFBQWE7WUFDVDlJLG1FQUFTQSxDQUFDLENBQUM2TCxJQUFJcEssT0FBT0MsSUFBSSxDQUFDbUssR0FBRzFELEtBQUssQ0FBQyxDQUFDUCxJQUFJLDZCQUE2QmtFLElBQUksQ0FBQ2xFLEtBQUssQ0FBQ2lFO2dCQUM3RSxNQUFNRSxVQUFVdEssT0FBT0MsSUFBSSxDQUFDbUssR0FBR2xFLE1BQU0sQ0FBQyxDQUFDQyxJQUFJLENBQUMsNkJBQTZCa0UsSUFBSSxDQUFDbEU7Z0JBQzlFLE9BQU8sQ0FBQyw2UEFBNlAsRUFBRW1FLFFBQVEvRCxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDaFM7U0FDSDtJQUNMO0FBQ0o7QUFDQTs7Q0FFQyxHQUFHLE1BQU1wRSx1QkFBdUI7SUFDN0Isc0JBQXNCO1FBQ2xCb0ksWUFBWTtZQUNSSixjQUFjO1lBQ2Q1QyxPQUFPdkosMkNBQUlBLENBQUN5SSxLQUFLO1lBQ2pCcEIsVUFBVSxFQUFFO1FBQ2hCO1FBQ0FtRixZQUFZO1lBQ1JMLGNBQWM7WUFDZDVDLE9BQU92SiwyQ0FBSUEsQ0FBQzJLLE1BQU07WUFDbEJ0RCxVQUFVb0Y7UUFDZDtJQUNKO0lBQ0EsR0FBR2pJLDBCQUEwQjtBQUNqQyIsInNvdXJjZXMiOlsid2VicGFjazovL0BvcGVubXJzL2VzbS1hcHAtc2hlbGwvLi4vLi4vZnJhbWV3b3JrL2VzbS1jb25maWcvZGlzdC9tb2R1bGUtY29uZmlnL21vZHVsZS1jb25maWcuanM/OGRmZSJdLCJzb3VyY2VzQ29udGVudCI6WyIvKiogQG1vZHVsZSBAY2F0ZWdvcnkgQ29uZmlnICovIGltcG9ydCB7IGNsb25lLCBlcXVhbHMsIHJlZHVjZSwgbWVyZ2VEZWVwUmlnaHQsIG9taXQgfSBmcm9tIFwicmFtZGFcIjtcbmltcG9ydCB7IFR5cGUgfSBmcm9tIFwiLi4vdHlwZXMuanNcIjtcbmltcG9ydCB7IGlzQXJyYXksIGlzQm9vbGVhbiwgaXNVdWlkLCBpc051bWJlciwgaXNPYmplY3QsIGlzU3RyaW5nIH0gZnJvbSBcIi4uL3ZhbGlkYXRvcnMvdHlwZS12YWxpZGF0b3JzLmpzXCI7XG5pbXBvcnQgeyB2YWxpZGF0b3IgfSBmcm9tIFwiLi4vdmFsaWRhdG9ycy92YWxpZGF0b3IuanNcIjtcbmltcG9ydCB7IGNvbmZpZ0V4dGVuc2lvblN0b3JlLCBjb25maWdJbnRlcm5hbFN0b3JlLCBnZXRDb25maWdTdG9yZSwgZ2V0RXh0ZW5zaW9uQ29uZmlnLCBnZXRFeHRlbnNpb25TbG90c0NvbmZpZ1N0b3JlLCBnZXRFeHRlbnNpb25zQ29uZmlnU3RvcmUsIGltcGxlbWVudGVyVG9vbHNDb25maWdTdG9yZSwgdGVtcG9yYXJ5Q29uZmlnU3RvcmUgfSBmcm9tIFwiLi9zdGF0ZS5qc1wiO1xuLyoqXG4gKiBTdG9yZSBzZXR1cFxuICpcbiAqXG4gKiBTZXQgdXAgc3RvcmVzIGFuZCBzdWJzY3JpcHRpb25zIHNvIHRoYXQgaW5wdXRzIGdldCBwcm9jZXNzZWQgYXBwcm9wcmlhdGVseS5cbiAqXG4gKiBUaGVyZSBhcmUgKmlucHV0KiBzdG9yZXMgYW5kICpvdXRwdXQqIHN0b3Jlcy4gVGhlICppbnB1dCogc3RvcmVzXG4gKiBhcmUgY29uZmlnSW50ZXJuYWxTdG9yZSwgdGVtcG9yYXJ5Q29uZmlnU3RvcmUsIGFuZCBjb25maWdFeHRlbnNpb25TdG9yZS4gVGhlXG4gKiBvdXRwdXQgc3RvcmVzIGFyZSBzZXQgaW4gdGhlIGBjb21wdXRlLi4uYCBmdW5jdGlvbnMuIFRoZXkgYXJlIHRoZSBtb2R1bGVcbiAqIGNvbmZpZyBzdG9yZXMsIHRoZSBleHRlbnNpb24gc2xvdCBjb25maWcgc3RvcmVzIChieSBtb2R1bGUpLCB0aGUgZXh0ZW5zaW9uXG4gKiBjb25maWcgc3RvcmVzLCBhbmQgdGhlIGltcGxlbWVudGVyIHRvb2xzIGNvbmZpZyBzdG9yZS5cbiAqXG4gKiBUaGlzIGNvZGUgc2V0cyB1cCB0aGUgc3Vic2NyaXB0aW9ucyBzbyB0aGF0IHdoZW4gYW4gaW5wdXQgc3RvcmUgY2hhbmdlcyxcbiAqIHRoZSBjb3JyZWN0IHNldCBvZiBvdXRwdXQgc3RvcmVzIGFyZSB1cGRhdGVkLlxuICpcbiAqIEFsbCBgY29tcHV0ZS4uLmAgZnVuY3Rpb25zIGV4Y2VwdCBgY29tcHV0ZUV4dGVuc2lvbkNvbmZpZ3NgIGFyZSBwdXJlXG4gKiAob3IgYXJlIHN1cHBvc2VkIHRvIGJlKSwgb3RoZXIgdGhhbiB0aGUgZmFjdCB0aGF0IHRoZXkgYWxsIGBzZXRTdGF0ZWBcbiAqIHN0b3JlIHZhbHVlcyBhdCB0aGUgZW5kLiBgY29tcHV0ZUV4dGVuc2lvbkNvbmZpZ3NgIGNhbGxzIGBnZXRHbG9iYWxTdG9yZWAsXG4gKiB3aGljaCBjcmVhdGVzIHN0b3Jlcy5cbiAqLyAvLyBTdG9yZSB1bnN1YnNjcmliZSBmdW5jdGlvbnMgdG8gYWxsb3cgY2xlYW51cCAoZS5nLiwgaW4gdGVzdHMgb3IgaG90IG1vZHVsZSByZWxvYWRpbmcpXG5jb25zdCBjb25maWdTdWJzY3JpcHRpb25zID0gW107XG4vKipcbiAqIFJlY29tcHV0ZXMgYWxsIGNvbmZpZ3VyYXRpb24gZGVyaXZlZCBzdG9yZXMgYmFzZWQgb24gY3VycmVudCBzdGF0ZSBvZiBpbnB1dCBzdG9yZXMuXG4gKiBDYWxsZWQgd2hlbmV2ZXIgYW55IGlucHV0IHN0b3JlIChjb25maWdJbnRlcm5hbFN0b3JlLCB0ZW1wb3JhcnlDb25maWdTdG9yZSwgY29uZmlnRXh0ZW5zaW9uU3RvcmUpIGNoYW5nZXMuXG4gKi8gZnVuY3Rpb24gcmVjb21wdXRlQWxsQ29uZmlncygpIHtcbiAgICBjb25zdCBjb25maWdTdGF0ZSA9IGNvbmZpZ0ludGVybmFsU3RvcmUuZ2V0U3RhdGUoKTtcbiAgICBjb25zdCB0ZW1wQ29uZmlnU3RhdGUgPSB0ZW1wb3JhcnlDb25maWdTdG9yZS5nZXRTdGF0ZSgpO1xuICAgIGNvbnN0IGV4dGVuc2lvblN0YXRlID0gY29uZmlnRXh0ZW5zaW9uU3RvcmUuZ2V0U3RhdGUoKTtcbiAgICBjb21wdXRlTW9kdWxlQ29uZmlnKGNvbmZpZ1N0YXRlLCB0ZW1wQ29uZmlnU3RhdGUpO1xuICAgIGNvbXB1dGVJbXBsZW1lbnRlclRvb2xzQ29uZmlnKGNvbmZpZ1N0YXRlLCB0ZW1wQ29uZmlnU3RhdGUpO1xuICAgIGNvbXB1dGVFeHRlbnNpb25TbG90Q29uZmlncyhjb25maWdTdGF0ZSwgdGVtcENvbmZpZ1N0YXRlKTtcbiAgICBjb21wdXRlRXh0ZW5zaW9uQ29uZmlncyhjb25maWdTdGF0ZSwgZXh0ZW5zaW9uU3RhdGUsIHRlbXBDb25maWdTdGF0ZSk7XG59XG5mdW5jdGlvbiBzZXR1cENvbmZpZ1N1YnNjcmlwdGlvbnMoKSB7XG4gICAgLy8gSW5pdGlhbCBjb21wdXRhdGlvblxuICAgIHJlY29tcHV0ZUFsbENvbmZpZ3MoKTtcbiAgICAvLyBTdWJzY3JpYmUgdG8gYWxsIGlucHV0IHN0b3JlcyB3aXRoIGEgc2luZ2xlIGhhbmRsZXJcbiAgICAvLyBUaGlzIGVuc3VyZXMgd2Ugb25seSByZWNvbXB1dGUgb25jZSBldmVuIGlmIG11bHRpcGxlIHN0b3JlcyBjaGFuZ2Ugc2ltdWx0YW5lb3VzbHlcbiAgICBjb25maWdTdWJzY3JpcHRpb25zLnB1c2goY29uZmlnSW50ZXJuYWxTdG9yZS5zdWJzY3JpYmUocmVjb21wdXRlQWxsQ29uZmlncykpO1xuICAgIGNvbmZpZ1N1YnNjcmlwdGlvbnMucHVzaCh0ZW1wb3JhcnlDb25maWdTdG9yZS5zdWJzY3JpYmUocmVjb21wdXRlQWxsQ29uZmlncykpO1xuICAgIGNvbmZpZ1N1YnNjcmlwdGlvbnMucHVzaChjb25maWdFeHRlbnNpb25TdG9yZS5zdWJzY3JpYmUocmVjb21wdXRlQWxsQ29uZmlncykpO1xufVxuLy8gU2V0IHVwIHN1YnNjcmlwdGlvbnMgYXQgbW9kdWxlIGxvYWQgdGltZVxuc2V0dXBDb25maWdTdWJzY3JpcHRpb25zKCk7XG5mdW5jdGlvbiBjb21wdXRlTW9kdWxlQ29uZmlnKHN0YXRlLCB0ZW1wU3RhdGUpIHtcbiAgICBmb3IgKGxldCBtb2R1bGVOYW1lIG9mIE9iamVjdC5rZXlzKHN0YXRlLnNjaGVtYXMpKXtcbiAgICAgICAgLy8gQXQgdGhpcyBwb2ludCB0aGUgc2NoZW1hIGNvdWxkIGJlIGVpdGhlciBqdXN0IHRoZSBpbXBsaWNpdCBzY2hlbWEgb3IgdGhlIGFjdHVhbGx5XG4gICAgICAgIC8vIGRlZmluZWQgc2NoZW1hLiBXZSBydW4gd2l0aCBqdXN0IHRoZSBpbXBsaWNpdCBzY2hlbWEgYmVjYXVzZSB3ZSB3YW50IHRvIHBvcHVsYXRlXG4gICAgICAgIC8vIHRoZSBjb25maWcgc3RvcmUgd2l0aCB0aGUgdHJhbnNsYXRpb24gb3ZlcnJpZGVzIGFzIHNvb24gYXMgcG9zc2libGUuIEluIGZhY3QsIHRoZVxuICAgICAgICAvLyB0cmFuc2xhdGlvbiBzeXN0ZW0gd2lsbCB0aHJvdyBmb3IgU3VzcGVuc2UgdW50aWwgdGhlIHRyYW5zbGF0aW9uIG92ZXJyaWRlcyBhcmVcbiAgICAgICAgLy8gYXZhaWxhYmxlLCB3aGljaCBhcyBvZiB0aGlzIHdyaXRpbmcgYmxvY2tzIHRoZSBzY2hlbWEgZGVmaW5pdGlvbiBmcm9tIG9jY3VycmluZ1xuICAgICAgICAvLyBmb3IgbW9kdWxlcyBsb2FkZWQgYmFzZWQgb24gdGhlaXIgZXh0ZW5zaW9ucy5cbiAgICAgICAgY29uc3QgbW9kdWxlU3RvcmUgPSBnZXRDb25maWdTdG9yZShtb2R1bGVOYW1lKTtcbiAgICAgICAgbGV0IG5ld1N0YXRlO1xuICAgICAgICBpZiAoc3RhdGUubW9kdWxlTG9hZGVkW21vZHVsZU5hbWVdKSB7XG4gICAgICAgICAgICBjb25zdCBjb25maWcgPSBnZXRDb25maWdGb3JNb2R1bGUobW9kdWxlTmFtZSwgc3RhdGUsIHRlbXBTdGF0ZSk7XG4gICAgICAgICAgICBuZXdTdGF0ZSA9IHtcbiAgICAgICAgICAgICAgICB0cmFuc2xhdGlvbk92ZXJyaWRlc0xvYWRlZDogdHJ1ZSxcbiAgICAgICAgICAgICAgICBsb2FkZWQ6IHRydWUsXG4gICAgICAgICAgICAgICAgY29uZmlnXG4gICAgICAgICAgICB9O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc3QgY29uZmlnID0gZ2V0Q29uZmlnRm9yTW9kdWxlSW1wbGljaXRTY2hlbWEobW9kdWxlTmFtZSwgc3RhdGUsIHRlbXBTdGF0ZSk7XG4gICAgICAgICAgICBuZXdTdGF0ZSA9IHtcbiAgICAgICAgICAgICAgICB0cmFuc2xhdGlvbk92ZXJyaWRlc0xvYWRlZDogdHJ1ZSxcbiAgICAgICAgICAgICAgICBsb2FkZWQ6IGZhbHNlLFxuICAgICAgICAgICAgICAgIGNvbmZpZ1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICBtb2R1bGVTdG9yZS5zZXRTdGF0ZShuZXdTdGF0ZSk7XG4gICAgfVxufVxuZnVuY3Rpb24gY29tcHV0ZUV4dGVuc2lvblNsb3RDb25maWdzKHN0YXRlLCB0ZW1wU3RhdGUpIHtcbiAgICBjb25zdCBzbG90Q29uZmlncyA9IGdldEV4dGVuc2lvblNsb3RDb25maWdzKHN0YXRlLCB0ZW1wU3RhdGUpO1xuICAgIGNvbnN0IG5ld1Nsb3RTdG9yZUVudHJpZXMgPSBPYmplY3QuZnJvbUVudHJpZXMoT2JqZWN0LmVudHJpZXMoc2xvdENvbmZpZ3MpLm1hcCgoW3Nsb3ROYW1lLCBjb25maWddKT0+W1xuICAgICAgICAgICAgc2xvdE5hbWUsXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgbG9hZGVkOiB0cnVlLFxuICAgICAgICAgICAgICAgIGNvbmZpZ1xuICAgICAgICAgICAgfVxuICAgICAgICBdKSk7XG4gICAgY29uc3Qgc2xvdFN0b3JlID0gZ2V0RXh0ZW5zaW9uU2xvdHNDb25maWdTdG9yZSgpO1xuICAgIGNvbnN0IG9sZFN0YXRlID0gc2xvdFN0b3JlLmdldFN0YXRlKCk7XG4gICAgY29uc3QgbmV3U3RhdGUgPSB7XG4gICAgICAgIHNsb3RzOiB7XG4gICAgICAgICAgICAuLi5vbGRTdGF0ZS5zbG90cyxcbiAgICAgICAgICAgIC4uLm5ld1Nsb3RTdG9yZUVudHJpZXNcbiAgICAgICAgfVxuICAgIH07XG4gICAgaWYgKCFlcXVhbHMob2xkU3RhdGUuc2xvdHMsIG5ld1N0YXRlLnNsb3RzKSkge1xuICAgICAgICBzbG90U3RvcmUuc2V0U3RhdGUobmV3U3RhdGUpO1xuICAgIH1cbn1cbmZ1bmN0aW9uIGNvbXB1dGVJbXBsZW1lbnRlclRvb2xzQ29uZmlnKHN0YXRlLCB0ZW1wQ29uZmlnU3RhdGUpIHtcbiAgICBjb25zdCBvbGRTdGF0ZSA9IGltcGxlbWVudGVyVG9vbHNDb25maWdTdG9yZS5nZXRTdGF0ZSgpO1xuICAgIGNvbnN0IGNvbmZpZyA9IGdldEltcGxlbWVudGVyVG9vbHNDb25maWcoc3RhdGUsIHRlbXBDb25maWdTdGF0ZSk7XG4gICAgY29uc3QgbmV3U3RhdGUgPSB7XG4gICAgICAgIGNvbmZpZ1xuICAgIH07XG4gICAgLy8gVXNlIGRlZXAgZXF1YWxpdHkgb24gdGhlIGFjdHVhbCBjb25maWcgY29udGVudCwgbm90IHRoZSB3cmFwcGVyIG9iamVjdFxuICAgIGlmICghZXF1YWxzKG9sZFN0YXRlLmNvbmZpZywgbmV3U3RhdGUuY29uZmlnKSkge1xuICAgICAgICBpbXBsZW1lbnRlclRvb2xzQ29uZmlnU3RvcmUuc2V0U3RhdGUobmV3U3RhdGUpO1xuICAgIH1cbn1cbmZ1bmN0aW9uIGNvbXB1dGVFeHRlbnNpb25Db25maWdzKGNvbmZpZ1N0YXRlLCBleHRlbnNpb25TdGF0ZSwgdGVtcENvbmZpZ1N0YXRlKSB7XG4gICAgY29uc3QgY29uZmlncyA9IHt9O1xuICAgIC8vIFdlIGFzc3VtZSB0aGF0IHRoZSBtb2R1bGUgc2NoZW1hIGhhcyBhbHJlYWR5IGJlZW4gZGVmaW5lZCwgc2luY2UgdGhlIGV4dGVuc2lvblxuICAgIC8vIGl0IGNvbnRhaW5zIGlzIG1vdW50ZWQuXG4gICAgZm9yIChsZXQgZXh0ZW5zaW9uIG9mIGV4dGVuc2lvblN0YXRlLm1vdW50ZWRFeHRlbnNpb25zKXtcbiAgICAgICAgY29uc3QgY29uZmlnID0gY29tcHV0ZUV4dGVuc2lvbkNvbmZpZyhleHRlbnNpb24uc2xvdE1vZHVsZU5hbWUsIGV4dGVuc2lvbi5leHRlbnNpb25Nb2R1bGVOYW1lLCBleHRlbnNpb24uc2xvdE5hbWUsIGV4dGVuc2lvbi5leHRlbnNpb25JZCwgY29uZmlnU3RhdGUsIHRlbXBDb25maWdTdGF0ZSk7XG4gICAgICAgIGlmICghY29uZmlnc1tleHRlbnNpb24uc2xvdE5hbWVdKSB7XG4gICAgICAgICAgICBjb25maWdzW2V4dGVuc2lvbi5zbG90TmFtZV0gPSB7fTtcbiAgICAgICAgfVxuICAgICAgICBjb25maWdzW2V4dGVuc2lvbi5zbG90TmFtZV1bZXh0ZW5zaW9uLmV4dGVuc2lvbklkXSA9IHtcbiAgICAgICAgICAgIGNvbmZpZyxcbiAgICAgICAgICAgIGxvYWRlZDogdHJ1ZVxuICAgICAgICB9O1xuICAgIH1cbiAgICBjb25zdCBleHRlbnNpb25zQ29uZmlnU3RvcmUgPSBnZXRFeHRlbnNpb25zQ29uZmlnU3RvcmUoKTtcbiAgICBjb25zdCBvbGRTdGF0ZSA9IGV4dGVuc2lvbnNDb25maWdTdG9yZS5nZXRTdGF0ZSgpO1xuICAgIGNvbnN0IG5ld1N0YXRlID0ge1xuICAgICAgICBjb25maWdzXG4gICAgfTtcbiAgICAvLyBVc2UgZGVlcCBlcXVhbGl0eSB0byBvbmx5IHVwZGF0ZSBpZiBjb25maWdzIGFjdHVhbGx5IGNoYW5nZWRcbiAgICBpZiAoIWVxdWFscyhvbGRTdGF0ZS5jb25maWdzLCBuZXdTdGF0ZS5jb25maWdzKSkge1xuICAgICAgICBleHRlbnNpb25zQ29uZmlnU3RvcmUuc2V0U3RhdGUobmV3U3RhdGUpO1xuICAgIH1cbn1cbi8qXG4gKiBBUElcbiAqXG4gKi8gLyoqXG4gKiBUaGlzIGRlZmluZXMgYSBjb25maWd1cmF0aW9uIHNjaGVtYSBmb3IgYSBtb2R1bGUuIFRoZSBzY2hlbWEgdGVsbHMgdGhlXG4gKiBjb25maWd1cmF0aW9uIHN5c3RlbSBob3cgdGhlIG1vZHVsZSBjYW4gYmUgY29uZmlndXJlZC4gSXQgc3BlY2lmaWVzXG4gKiB3aGF0IG1ha2VzIGNvbmZpZ3VyYXRpb24gdmFsaWQgb3IgaW52YWxpZC5cbiAqXG4gKiBTZWUgW0NvbmZpZ3VyYXRpb24gU3lzdGVtXShodHRwczovL28zLWRvY3Mub3Blbm1ycy5vcmcvZG9jcy9jb25maWd1cmF0aW9uLXN5c3RlbSlcbiAqIGZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IGRlZmluaW5nIGEgY29uZmlnIHNjaGVtYS5cbiAqXG4gKiBAcGFyYW0gbW9kdWxlTmFtZSBOYW1lIG9mIHRoZSBtb2R1bGUgdGhlIHNjaGVtYSBpcyBiZWluZyBkZWZpbmVkIGZvci4gR2VuZXJhbGx5XG4gKiAgIHNob3VsZCBiZSB0aGUgb25lIGluIHdoaWNoIHRoZSBgZGVmaW5lQ29uZmlnU2NoZW1hYCBjYWxsIHRha2VzIHBsYWNlLlxuICogQHBhcmFtIHNjaGVtYSBUaGUgY29uZmlnIHNjaGVtYSBmb3IgdGhlIG1vZHVsZVxuICovIGV4cG9ydCBmdW5jdGlvbiBkZWZpbmVDb25maWdTY2hlbWEobW9kdWxlTmFtZSwgc2NoZW1hKSB7XG4gICAgdmFsaWRhdGVDb25maWdTY2hlbWEobW9kdWxlTmFtZSwgc2NoZW1hKTtcbiAgICBjb25zdCBlbmhhbmNlZFNjaGVtYSA9IG1lcmdlRGVlcFJpZ2h0KHNjaGVtYSwgaW1wbGljaXRDb25maWdTY2hlbWEpO1xuICAgIGNvbmZpZ0ludGVybmFsU3RvcmUuc2V0U3RhdGUoKHN0YXRlKT0+KHtcbiAgICAgICAgICAgIC4uLnN0YXRlLFxuICAgICAgICAgICAgc2NoZW1hczoge1xuICAgICAgICAgICAgICAgIC4uLnN0YXRlLnNjaGVtYXMsXG4gICAgICAgICAgICAgICAgW21vZHVsZU5hbWVdOiBlbmhhbmNlZFNjaGVtYVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIG1vZHVsZUxvYWRlZDoge1xuICAgICAgICAgICAgICAgIC4uLnN0YXRlLm1vZHVsZUxvYWRlZCxcbiAgICAgICAgICAgICAgICBbbW9kdWxlTmFtZV06IHRydWVcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSkpO1xufVxuLyoqXG4gKiBUaGlzIGFsZXJ0cyB0aGUgY29uZmlndXJhdGlvbiBzeXN0ZW0gdGhhdCBhIG1vZHVsZSBleGlzdHMuIFRoaXMgYWxsb3dzIGNvbmZpZyB0byBiZVxuICogcHJvY2Vzc2VkLCB3aGlsZSBzdGlsbCBhbGxvd2luZyB0aGUgZXh0ZW5zaW9uIHN5c3RlbSB0byBrbm93IHdoZXRoZXIgdGhlIG1vZHVsZSBoYXNcbiAqIGFjdHVhbGx5IGhhZCBpdHMgZnJvbnQgYnVuZGxlIGV4ZWN1dGVkIHlldC5cbiAqXG4gKiBUaGlzIHNob3VsZCBvbmx5IGJlIHVzZWQgaW4gZXNtLWFwcC1zaGVsbC5cbiAqXG4gKiBAaW50ZXJuYWxcbiAqIEBwYXJhbSBtb2R1bGVOYW1lXG4gKi8gZXhwb3J0IGZ1bmN0aW9uIHJlZ2lzdGVyTW9kdWxlV2l0aENvbmZpZ1N5c3RlbShtb2R1bGVOYW1lKSB7XG4gICAgY29uZmlnSW50ZXJuYWxTdG9yZS5zZXRTdGF0ZSgoc3RhdGUpPT4oe1xuICAgICAgICAgICAgLi4uc3RhdGUsXG4gICAgICAgICAgICBzY2hlbWFzOiB7XG4gICAgICAgICAgICAgICAgLi4uc3RhdGUuc2NoZW1hcyxcbiAgICAgICAgICAgICAgICBbbW9kdWxlTmFtZV06IGltcGxpY2l0Q29uZmlnU2NoZW1hXG4gICAgICAgICAgICB9XG4gICAgICAgIH0pKTtcbn1cbi8qKlxuICogVGhpcyBhbGVydHMgdGhlIGNvbmZpZ3VyYXRpb24gc3lzdGVtIHRoYXQgYSBtb2R1bGUgaGFzIGJlZW4gbG9hZGVkLlxuICpcbiAqIFRoaXMgc2hvdWxkIG9ubHkgYmUgdXNlZCBpbiBlc20tYXBwLXNoZWxsLlxuICpcbiAqIEBpbnRlcm5hbFxuICogQHBhcmFtIG1vZHVsZU5hbWVcbiAqLyBleHBvcnQgZnVuY3Rpb24gcmVnaXN0ZXJNb2R1bGVMb2FkKG1vZHVsZU5hbWUpIHtcbiAgICBjb25maWdJbnRlcm5hbFN0b3JlLnNldFN0YXRlKChzdGF0ZSk9Pih7XG4gICAgICAgICAgICAuLi5zdGF0ZSxcbiAgICAgICAgICAgIG1vZHVsZUxvYWRlZDoge1xuICAgICAgICAgICAgICAgIC4uLnN0YXRlLm1vZHVsZUxvYWRlZCxcbiAgICAgICAgICAgICAgICBbbW9kdWxlTmFtZV06IHRydWVcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSkpO1xufVxuLyoqXG4gKiBUaGlzIGFsbG93cyB0aGUgY29uZmlnIHN5c3RlbSB0byBzdXBwb3J0IHRyYW5zbGF0aW9uIG92ZXJyaWRlcyBmb3IgbmFtZXNwYWNlcyB0aGF0XG4gKiBkbyBub3QgY29ycmVzcG9uZCB0byBtb2R1bGVzLlxuICpcbiAqIFRoaXMgc2hvdWxkIG9ubHkgYmUgdXNlZCBpbiBlc20tYXBwLXNoZWxsLlxuICpcbiAqIEBpbnRlcm5hbFxuICogQHBhcmFtIG5hbWVzcGFjZVxuICovIGV4cG9ydCBmdW5jdGlvbiByZWdpc3RlclRyYW5zbGF0aW9uTmFtZXNwYWNlKG5hbWVzcGFjZSkge1xuICAgIGNvbmZpZ0ludGVybmFsU3RvcmUuc2V0U3RhdGUoKHN0YXRlKT0+KHtcbiAgICAgICAgICAgIC4uLnN0YXRlLFxuICAgICAgICAgICAgc2NoZW1hczoge1xuICAgICAgICAgICAgICAgIC4uLnN0YXRlLnNjaGVtYXMsXG4gICAgICAgICAgICAgICAgW25hbWVzcGFjZV06IHRyYW5zbGF0aW9uT3ZlcnJpZGVzU2NoZW1hXG4gICAgICAgICAgICB9XG4gICAgICAgIH0pKTtcbn1cbi8qKlxuICogVGhpcyBkZWZpbmVzIGEgY29uZmlndXJhdGlvbiBzY2hlbWEgZm9yIGFuIGV4dGVuc2lvbi4gV2hlbiBhIHNjaGVtYSBpcyBkZWZpbmVkXG4gKiBmb3IgYW4gZXh0ZW5zaW9uLCB0aGF0IGV4dGVuc2lvbiB3aWxsIHJlY2VpdmUgdGhlIGNvbmZpZ3VyYXRpb24gY29ycmVzcG9uZGluZ1xuICogdG8gdGhhdCBzY2hlbWEsIHJhdGhlciB0aGFuIHRoZSBjb25maWd1cmF0aW9uIGNvcnJlc3BvbmRpbmcgdG8gdGhlIG1vZHVsZVxuICogaW4gd2hpY2ggaXQgaXMgZGVmaW5lZC5cbiAqXG4gKiBUaGUgc2NoZW1hIHRlbGxzIHRoZSBjb25maWd1cmF0aW9uIHN5c3RlbSBob3cgdGhlIG1vZHVsZSBjYW4gYmUgY29uZmlndXJlZC5cbiAqIEl0IHNwZWNpZmllcyB3aGF0IG1ha2VzIGNvbmZpZ3VyYXRpb24gdmFsaWQgb3IgaW52YWxpZC5cbiAqXG4gKiBTZWUgW0NvbmZpZ3VyYXRpb24gU3lzdGVtXShodHRwczovL28zLWRvY3Mub3Blbm1ycy5vcmcvZG9jcy9jb25maWd1cmF0aW9uLXN5c3RlbSlcbiAqIGZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IGRlZmluaW5nIGEgY29uZmlnIHNjaGVtYS5cbiAqXG4gKiBAcGFyYW0gZXh0ZW5zaW9uTmFtZSBOYW1lIG9mIHRoZSBleHRlbnNpb24gdGhlIHNjaGVtYSBpcyBiZWluZyBkZWZpbmVkIGZvci5cbiAqICAgU2hvdWxkIG1hdGNoIHRoZSBgbmFtZWAgb2Ygb25lIG9mIHRoZSBgZXh0ZW5zaW9uc2AgZW50cmllcyBkZWZpbmVkIGluXG4gKiAgIHRoZSBhcHAncyBgcm91dGVzLmpzb25gIGZpbGUuXG4gKiBAcGFyYW0gc2NoZW1hIFRoZSBjb25maWcgc2NoZW1hIGZvciB0aGUgZXh0ZW5zaW9uXG4gKi8gZXhwb3J0IGZ1bmN0aW9uIGRlZmluZUV4dGVuc2lvbkNvbmZpZ1NjaGVtYShleHRlbnNpb25OYW1lLCBzY2hlbWEpIHtcbiAgICB2YWxpZGF0ZUNvbmZpZ1NjaGVtYShleHRlbnNpb25OYW1lLCBzY2hlbWEpO1xuICAgIGNvbnN0IGVuaGFuY2VkU2NoZW1hID0gbWVyZ2VEZWVwUmlnaHQoc2NoZW1hLCBpbXBsaWNpdENvbmZpZ1NjaGVtYSk7XG4gICAgY29uc3Qgc3RhdGUgPSBjb25maWdJbnRlcm5hbFN0b3JlLmdldFN0YXRlKCk7XG4gICAgaWYgKHN0YXRlLnNjaGVtYXNbZXh0ZW5zaW9uTmFtZV0pIHtcbiAgICAgICAgY29uc29sZS5lcnJvcihgQ29uZmlnIHNjaGVtYSBmb3IgZXh0ZW5zaW9uICR7ZXh0ZW5zaW9uTmFtZX0gYWxyZWFkeSBleGlzdHMuIElmIHRoZXJlIGFyZSBtdWx0aXBsZSBleHRlbnNpb25zIHdpdGggdGhpcyBzYW1lIG5hbWUsIG9uZSB3aWxsIHByb2JhYmx5IGNyYXNoLmApO1xuICAgIH1cbiAgICBjb25maWdJbnRlcm5hbFN0b3JlLnNldFN0YXRlKChzdGF0ZSk9Pih7XG4gICAgICAgICAgICAuLi5zdGF0ZSxcbiAgICAgICAgICAgIHNjaGVtYXM6IHtcbiAgICAgICAgICAgICAgICAuLi5zdGF0ZS5zY2hlbWFzLFxuICAgICAgICAgICAgICAgIFtleHRlbnNpb25OYW1lXTogZW5oYW5jZWRTY2hlbWFcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSkpO1xufVxuZXhwb3J0IGZ1bmN0aW9uIHByb3ZpZGUoY29uZmlnLCBzb3VyY2VOYW1lID0gJ3Byb3ZpZGVkJykge1xuICAgIGNvbmZpZ0ludGVybmFsU3RvcmUuc2V0U3RhdGUoKHN0YXRlKT0+KHtcbiAgICAgICAgICAgIC4uLnN0YXRlLFxuICAgICAgICAgICAgcHJvdmlkZWRDb25maWdzOiBbXG4gICAgICAgICAgICAgICAgLi4uc3RhdGUucHJvdmlkZWRDb25maWdzLFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgc291cmNlOiBzb3VyY2VOYW1lLFxuICAgICAgICAgICAgICAgICAgICBjb25maWdcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBdXG4gICAgICAgIH0pKTtcbn1cbi8qKlxuICogQSBwcm9taXNlLWJhc2VkIHdheSB0byBhY2Nlc3MgdGhlIGNvbmZpZyBhcyBzb29uIGFzIGl0IGlzIGZ1bGx5IGxvYWRlZC5cbiAqIElmIGl0IGlzIGFscmVhZHkgbG9hZGVkLCByZXNvbHZlcyB0aGUgY29uZmlnIGluIGl0cyBwcmVzZW50IHN0YXRlLlxuICpcbiAqIFRoaXMgaXMgYSB1c2VmdWwgZnVuY3Rpb24gaWYgeW91IG5lZWQgdG8gZ2V0IHRoZSBjb25maWcgaW4gdGhlIGNvdXJzZVxuICogb2YgdGhlIGV4ZWN1dGlvbiBvZiBhIGZ1bmN0aW9uLlxuICpcbiAqIEBwYXJhbSBtb2R1bGVOYW1lIFRoZSBuYW1lIG9mIHRoZSBtb2R1bGUgZm9yIHdoaWNoIHRvIGxvb2sgdXAgdGhlIGNvbmZpZ1xuICovIGV4cG9ydCBmdW5jdGlvbiBnZXRDb25maWcobW9kdWxlTmFtZSkge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSk9PntcbiAgICAgICAgY29uc3Qgc3RvcmUgPSBnZXRDb25maWdTdG9yZShtb2R1bGVOYW1lKTtcbiAgICAgICAgZnVuY3Rpb24gdXBkYXRlKHN0YXRlKSB7XG4gICAgICAgICAgICBpZiAoc3RhdGUubG9hZGVkICYmIHN0YXRlLmNvbmZpZykge1xuICAgICAgICAgICAgICAgIGNvbnN0IGNvbmZpZyA9IG9taXQoW1xuICAgICAgICAgICAgICAgICAgICAnRGlzcGxheSBjb25kaXRpb25zJyxcbiAgICAgICAgICAgICAgICAgICAgJ1RyYW5zbGF0aW9uIG92ZXJyaWRlcydcbiAgICAgICAgICAgICAgICBdLCBzdGF0ZS5jb25maWcpO1xuICAgICAgICAgICAgICAgIHJlc29sdmUoY29uZmlnKTtcbiAgICAgICAgICAgICAgICBpZiAodW5zdWJzY3JpYmUpIHtcbiAgICAgICAgICAgICAgICAgICAgdW5zdWJzY3JpYmUoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdXBkYXRlKHN0b3JlLmdldFN0YXRlKCkpO1xuICAgICAgICBjb25zdCB1bnN1YnNjcmliZSA9IHN0b3JlLnN1YnNjcmliZSh1cGRhdGUpO1xuICAgIH0pO1xufVxuLyoqIEBpbnRlcm5hbCAqLyBleHBvcnQgZnVuY3Rpb24gZ2V0VHJhbnNsYXRpb25PdmVycmlkZXMobW9kdWxlTmFtZSwgc2xvdE5hbWUsIGV4dGVuc2lvbklkKSB7XG4gICAgY29uc3QgcHJvbWlzZXMgPSBbXG4gICAgICAgIG5ldyBQcm9taXNlKChyZXNvbHZlKT0+e1xuICAgICAgICAgICAgY29uc3QgY29uZmlnU3RvcmUgPSBnZXRDb25maWdTdG9yZShtb2R1bGVOYW1lKTtcbiAgICAgICAgICAgIGZ1bmN0aW9uIHVwZGF0ZShzdGF0ZSkge1xuICAgICAgICAgICAgICAgIGlmIChzdGF0ZS50cmFuc2xhdGlvbk92ZXJyaWRlc0xvYWRlZCAmJiBzdGF0ZS5jb25maWcpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdHJhbnNsYXRpb25PdmVycmlkZXMgPSBzdGF0ZS5jb25maWdbJ1RyYW5zbGF0aW9uIG92ZXJyaWRlcyddID8/IHt9O1xuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHRyYW5zbGF0aW9uT3ZlcnJpZGVzKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHVuc3Vic2NyaWJlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB1bnN1YnNjcmliZSgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdXBkYXRlKGNvbmZpZ1N0b3JlLmdldFN0YXRlKCkpO1xuICAgICAgICAgICAgY29uc3QgdW5zdWJzY3JpYmUgPSBjb25maWdTdG9yZS5zdWJzY3JpYmUodXBkYXRlKTtcbiAgICAgICAgfSlcbiAgICBdO1xuICAgIGlmIChzbG90TmFtZSAmJiBleHRlbnNpb25JZCkge1xuICAgICAgICBwcm9taXNlcy5wdXNoKG5ldyBQcm9taXNlKChyZXNvbHZlKT0+e1xuICAgICAgICAgICAgY29uc3QgY29uZmlnU3RvcmUgPSBnZXRFeHRlbnNpb25Db25maWcoc2xvdE5hbWUsIGV4dGVuc2lvbklkKTtcbiAgICAgICAgICAgIGZ1bmN0aW9uIHVwZGF0ZShzdGF0ZSkge1xuICAgICAgICAgICAgICAgIGlmIChzdGF0ZS5sb2FkZWQgJiYgc3RhdGUuY29uZmlnKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHRyYW5zbGF0aW9uT3ZlcnJpZGVzID0gc3RhdGUuY29uZmlnWydUcmFuc2xhdGlvbiBvdmVycmlkZXMnXSA/PyB7fTtcbiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSh0cmFuc2xhdGlvbk92ZXJyaWRlcyk7XG4gICAgICAgICAgICAgICAgICAgIGlmICh1bnN1YnNjcmliZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdW5zdWJzY3JpYmUoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHVwZGF0ZShjb25maWdTdG9yZS5nZXRTdGF0ZSgpKTtcbiAgICAgICAgICAgIGNvbnN0IHVuc3Vic2NyaWJlID0gY29uZmlnU3RvcmUuc3Vic2NyaWJlKHVwZGF0ZSk7XG4gICAgICAgIH0pKTtcbiAgICB9XG4gICAgcmV0dXJuIFByb21pc2UuYWxsKHByb21pc2VzKTtcbn1cbi8qKlxuICogVmFsaWRhdGUgYW5kIGludGVycG9sYXRlIGRlZmF1bHRzIGZvciBgcHJvdmlkZWRDb25maWdgIGFjY29yZGluZyB0byBgc2NoZW1hYFxuICpcbiAqIEBwYXJhbSBzY2hlbWEgIGEgY29uZmlndXJhdGlvbiBzY2hlbWFcbiAqIEBwYXJhbSBwcm92aWRlZENvbmZpZyAgYW4gb2JqZWN0IG9mIGNvbmZpZyB2YWx1ZXMgKHdpdGhvdXQgdGhlIHRvcC1sZXZlbCBtb2R1bGUgbmFtZSlcbiAqIEBwYXJhbSBrZXlQYXRoQ29udGV4dCAgYSBkb3QtZGVwYXJhdGVkIHN0cmluZyB3aGljaCBoZWxwcyB0aGUgdXNlciBmaWd1cmUgb3V0IHdoZXJlXG4gKiAgICAgdGhlIHByb3ZpZGVkIGNvbmZpZyBjYW1lIGZyb21cbiAqIEBpbnRlcm5hbFxuICovIGV4cG9ydCBmdW5jdGlvbiBwcm9jZXNzQ29uZmlnKHNjaGVtYSwgcHJvdmlkZWRDb25maWcsIGtleVBhdGhDb250ZXh0KSB7XG4gICAgdmFsaWRhdGVTdHJ1Y3R1cmUoc2NoZW1hLCBwcm92aWRlZENvbmZpZywga2V5UGF0aENvbnRleHQpO1xuICAgIGNvbnN0IGNvbmZpZyA9IHNldERlZmF1bHRzKHNjaGVtYSwgcHJvdmlkZWRDb25maWcpO1xuICAgIHJ1bkFsbFZhbGlkYXRvcnNJbkNvbmZpZ1RyZWUoc2NoZW1hLCBjb25maWcsIGtleVBhdGhDb250ZXh0KTtcbiAgICByZXR1cm4gY29uZmlnO1xufVxuLypcbiAqIEhlbHBlciBmdW5jdGlvbnNcbiAqXG4gKi8gLyoqXG4gKiBSZXR1cm5zIHRoZSBjb25maWd1cmF0aW9uIGZvciBhbiBleHRlbnNpb24uIFRoaXMgY29uZmlndXJhdGlvbiBpcyBzcGVjaWZpY1xuICogdG8gdGhlIHNsb3QgaW4gd2hpY2ggaXQgaXMgbW91bnRlZCwgYW5kIGl0cyBJRCB3aXRoaW4gdGhhdCBzbG90LlxuICpcbiAqIFRoZSBzY2hlbWEgZm9yIHRoYXQgY29uZmlndXJhdGlvbiBpcyB0aGUgZXh0ZW5zaW9uIHNjaGVtYS4gSWYgbm8gZXh0ZW5zaW9uXG4gKiBzY2hlbWEgaGFzIGJlZW4gcHJvdmlkZWQsIHRoZSBzY2hlbWEgdXNlZCBpcyB0aGUgc2NoZW1hIG9mIHRoZSBtb2R1bGUgaW5cbiAqIHdoaWNoIHRoZSBleHRlbnNpb24gaXMgZGVmaW5lZC5cbiAqXG4gKiBAcGFyYW0gc2xvdE1vZHVsZU5hbWUgVGhlIG5hbWUgb2YgdGhlIG1vZHVsZSB3aGljaCBkZWZpbmVzIHRoZSBleHRlbnNpb24gc2xvdFxuICogQHBhcmFtIGV4dGVuc2lvbk1vZHVsZU5hbWUgVGhlIG5hbWUgb2YgdGhlIG1vZHVsZSB3aGljaCBkZWZpbmVzIHRoZSBleHRlbnNpb24gKGFuZCB0aGVyZWZvcmUgdGhlIGNvbmZpZyBzY2hlbWEpXG4gKiBAcGFyYW0gc2xvdE5hbWUgVGhlIG5hbWUgb2YgdGhlIGV4dGVuc2lvbiBzbG90IHdoZXJlIHRoZSBleHRlbnNpb24gaXMgbW91bnRlZFxuICogQHBhcmFtIGV4dGVuc2lvbklkIFRoZSBJRCBvZiB0aGUgZXh0ZW5zaW9uIGluIGl0cyBzbG90XG4gKi8gZnVuY3Rpb24gY29tcHV0ZUV4dGVuc2lvbkNvbmZpZyhzbG90TW9kdWxlTmFtZSwgZXh0ZW5zaW9uTW9kdWxlTmFtZSwgc2xvdE5hbWUsIGV4dGVuc2lvbklkLCBjb25maWdTdGF0ZSwgdGVtcENvbmZpZ1N0YXRlKSB7XG4gICAgY29uc3QgZXh0ZW5zaW9uTmFtZSA9IGdldEV4dGVuc2lvbk5hbWVGcm9tSWQoZXh0ZW5zaW9uSWQpO1xuICAgIGNvbnN0IGV4dGVuc2lvbkNvbmZpZ1NjaGVtYSA9IGNvbmZpZ1N0YXRlLnNjaGVtYXNbZXh0ZW5zaW9uTmFtZV07XG4gICAgY29uc3QgbmFtZU9mU2NoZW1hU291cmNlID0gZXh0ZW5zaW9uQ29uZmlnU2NoZW1hID8gZXh0ZW5zaW9uTmFtZSA6IGV4dGVuc2lvbk1vZHVsZU5hbWU7XG4gICAgY29uc3QgcHJvdmlkZWRDb25maWdzID0gZ2V0UHJvdmlkZWRDb25maWdzKGNvbmZpZ1N0YXRlLCB0ZW1wQ29uZmlnU3RhdGUpO1xuICAgIGNvbnN0IHNsb3RNb2R1bGVDb25maWcgPSBtZXJnZUNvbmZpZ3NGb3Ioc2xvdE1vZHVsZU5hbWUsIHByb3ZpZGVkQ29uZmlncyk7XG4gICAgY29uc3QgY29uZmlnT3ZlcnJpZGUgPSBzbG90TW9kdWxlQ29uZmlnPy5leHRlbnNpb25TbG90cz8uW3Nsb3ROYW1lXT8uY29uZmlndXJlPy5bZXh0ZW5zaW9uSWRdID8/IHt9O1xuICAgIGNvbnN0IGV4dGVuc2lvbkNvbmZpZyA9IG1lcmdlQ29uZmlnc0ZvcihuYW1lT2ZTY2hlbWFTb3VyY2UsIHByb3ZpZGVkQ29uZmlncyk7XG4gICAgY29uc3QgY29tYmluZWRDb25maWcgPSBtZXJnZUNvbmZpZ3MoW1xuICAgICAgICBleHRlbnNpb25Db25maWcsXG4gICAgICAgIGNvbmZpZ092ZXJyaWRlXG4gICAgXSk7XG4gICAgY29uc3Qgc2NoZW1hID0gZXh0ZW5zaW9uQ29uZmlnU2NoZW1hID8/IGNvbmZpZ1N0YXRlLnNjaGVtYXNbZXh0ZW5zaW9uTW9kdWxlTmFtZV07XG4gICAgdmFsaWRhdGVTdHJ1Y3R1cmUoc2NoZW1hLCBjb21iaW5lZENvbmZpZywgbmFtZU9mU2NoZW1hU291cmNlKTtcbiAgICBjb25zdCBjb25maWcgPSBzZXREZWZhdWx0cyhzY2hlbWEsIGNvbWJpbmVkQ29uZmlnKTtcbiAgICBydW5BbGxWYWxpZGF0b3JzSW5Db25maWdUcmVlKHNjaGVtYSwgY29uZmlnLCBuYW1lT2ZTY2hlbWFTb3VyY2UpO1xuICAgIGRlbGV0ZSBjb25maWcuZXh0ZW5zaW9uU2xvdHM7XG4gICAgcmV0dXJuIGNvbmZpZztcbn1cbmZ1bmN0aW9uIGdldEltcGxlbWVudGVyVG9vbHNDb25maWcoY29uZmlnU3RhdGUsIHRlbXBDb25maWdTdGF0ZSkge1xuICAgIGxldCByZXN1bHQgPSBnZXRTY2hlbWFXaXRoVmFsdWVzQW5kU291cmNlcyhjbG9uZShjb25maWdTdGF0ZS5zY2hlbWFzKSk7XG4gICAgY29uc3QgY29uZmlnc0FuZFNvdXJjZXMgPSBbXG4gICAgICAgIC4uLmNvbmZpZ1N0YXRlLnByb3ZpZGVkQ29uZmlncy5tYXAoKGMpPT5bXG4gICAgICAgICAgICAgICAgYy5jb25maWcsXG4gICAgICAgICAgICAgICAgYy5zb3VyY2VcbiAgICAgICAgICAgIF0pLFxuICAgICAgICBbXG4gICAgICAgICAgICB0ZW1wQ29uZmlnU3RhdGUuY29uZmlnLFxuICAgICAgICAgICAgJ3RlbXBvcmFyeSBjb25maWcnXG4gICAgICAgIF1cbiAgICBdO1xuICAgIGZvciAobGV0IFtjb25maWcsIHNvdXJjZV0gb2YgY29uZmlnc0FuZFNvdXJjZXMpe1xuICAgICAgICByZXN1bHQgPSBtZXJnZUNvbmZpZ3MoW1xuICAgICAgICAgICAgcmVzdWx0LFxuICAgICAgICAgICAgY3JlYXRlVmFsdWVzQW5kU291cmNlc1RyZWUoY29uZmlnLCBzb3VyY2UpXG4gICAgICAgIF0pO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xufVxuZnVuY3Rpb24gZ2V0U2NoZW1hV2l0aFZhbHVlc0FuZFNvdXJjZXMoc2NoZW1hKSB7XG4gICAgaWYgKHNjaGVtYS5oYXNPd25Qcm9wZXJ0eSgnX2RlZmF1bHQnKSkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgLi4uc2NoZW1hLFxuICAgICAgICAgICAgX3ZhbHVlOiBzY2hlbWEuX2RlZmF1bHQsXG4gICAgICAgICAgICBfc291cmNlOiAnZGVmYXVsdCdcbiAgICAgICAgfTtcbiAgICB9IGVsc2UgaWYgKGlzT3JkaW5hcnlPYmplY3Qoc2NoZW1hKSkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmtleXMoc2NoZW1hKS5yZWR1Y2UoKG9iaiwga2V5KT0+e1xuICAgICAgICAgICAgb2JqW2tleV0gPSBnZXRTY2hlbWFXaXRoVmFsdWVzQW5kU291cmNlcyhzY2hlbWFba2V5XSk7XG4gICAgICAgICAgICByZXR1cm4gb2JqO1xuICAgICAgICB9LCB7fSk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgLy8gYXQgdGhpcyBwb2ludCwgdGhlIHNjaGVtYSBpcyBiYWQgYW5kIGFuIGVycm9yIHdpbGwgaGF2ZSBiZWVuIGxvZ2dlZCBkdXJpbmcgc2NoZW1hIHZhbGlkYXRpb25cbiAgICAgICAgcmV0dXJuIHt9O1xuICAgIH1cbn1cbmZ1bmN0aW9uIGNyZWF0ZVZhbHVlc0FuZFNvdXJjZXNUcmVlKGNvbmZpZywgc291cmNlKSB7XG4gICAgaWYgKGlzT3JkaW5hcnlPYmplY3QoY29uZmlnKSkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmtleXMoY29uZmlnKS5yZWR1Y2UoKG9iaiwga2V5KT0+e1xuICAgICAgICAgICAgb2JqW2tleV0gPSBjcmVhdGVWYWx1ZXNBbmRTb3VyY2VzVHJlZShjb25maWdba2V5XSwgc291cmNlKTtcbiAgICAgICAgICAgIHJldHVybiBvYmo7XG4gICAgICAgIH0sIHt9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgX3ZhbHVlOiBjb25maWcsXG4gICAgICAgICAgICBfc291cmNlOiBzb3VyY2VcbiAgICAgICAgfTtcbiAgICB9XG59XG5mdW5jdGlvbiBnZXRFeHRlbnNpb25TbG90Q29uZmlncyhjb25maWdTdGF0ZSwgdGVtcENvbmZpZ1N0YXRlKSB7XG4gICAgY29uc3QgYWxsQ29uZmlncyA9IG1lcmdlQ29uZmlncyhnZXRQcm92aWRlZENvbmZpZ3MoY29uZmlnU3RhdGUsIHRlbXBDb25maWdTdGF0ZSkpO1xuICAgIGNvbnN0IHNsb3RDb25maWdQZXJNb2R1bGUgPSBPYmplY3Qua2V5cyhhbGxDb25maWdzKS5yZWR1Y2UoKG9iaiwga2V5KT0+e1xuICAgICAgICBpZiAoYWxsQ29uZmlnc1trZXldPy5leHRlbnNpb25TbG90cykge1xuICAgICAgICAgICAgb2JqW2tleV0gPSBhbGxDb25maWdzW2tleV0/LmV4dGVuc2lvblNsb3RzO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBvYmo7XG4gICAgfSwge30pO1xuICAgIHZhbGlkYXRlQWxsRXh0ZW5zaW9uU2xvdENvbmZpZ3Moc2xvdENvbmZpZ1Blck1vZHVsZSk7XG4gICAgY29uc3Qgc2xvdENvbmZpZ3MgPSBPYmplY3Qua2V5cyhzbG90Q29uZmlnUGVyTW9kdWxlKS5yZWR1Y2UoKG9iaiwga2V5KT0+e1xuICAgICAgICBvYmogPSB7XG4gICAgICAgICAgICAuLi5vYmosXG4gICAgICAgICAgICAuLi5zbG90Q29uZmlnUGVyTW9kdWxlW2tleV1cbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIG9iajtcbiAgICB9LCB7fSk7XG4gICAgcmV0dXJuIHNsb3RDb25maWdzO1xufVxuZnVuY3Rpb24gdmFsaWRhdGVBbGxFeHRlbnNpb25TbG90Q29uZmlncyhzbG90Q29uZmlnUGVyTW9kdWxlKSB7XG4gICAgZm9yIChsZXQgW21vZHVsZU5hbWUsIGNvbmZpZ0J5U2xvdE5hbWVdIG9mIE9iamVjdC5lbnRyaWVzKHNsb3RDb25maWdQZXJNb2R1bGUpKXtcbiAgICAgICAgZm9yIChsZXQgW3Nsb3ROYW1lLCBjb25maWddIG9mIE9iamVjdC5lbnRyaWVzKGNvbmZpZ0J5U2xvdE5hbWUpKXtcbiAgICAgICAgICAgIHZhbGlkYXRlRXh0ZW5zaW9uU2xvdENvbmZpZyhjb25maWcsIG1vZHVsZU5hbWUsIHNsb3ROYW1lKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbmZ1bmN0aW9uIHZhbGlkYXRlRXh0ZW5zaW9uU2xvdENvbmZpZyhjb25maWcsIG1vZHVsZU5hbWUsIHNsb3ROYW1lKSB7XG4gICAgY29uc3Qga2V5UGF0aCA9IGAke21vZHVsZU5hbWV9LmV4dGVuc2lvblNsb3RzLiR7c2xvdE5hbWV9YDtcbiAgICBjb25zdCBlcnJvclByZWZpeCA9IGBFeHRlbnNpb24gc2xvdCBjb25maWcgJyR7a2V5UGF0aH0nYDtcbiAgICBjb25zdCBpbnZhbGlkS2V5cyA9IE9iamVjdC5rZXlzKGNvbmZpZykuZmlsdGVyKChrKT0+IVtcbiAgICAgICAgICAgICdhZGQnLFxuICAgICAgICAgICAgJ3JlbW92ZScsXG4gICAgICAgICAgICAnb3JkZXInLFxuICAgICAgICAgICAgJ2NvbmZpZ3VyZSdcbiAgICAgICAgXS5pbmNsdWRlcyhrKSk7XG4gICAgaWYgKGludmFsaWRLZXlzLmxlbmd0aCkge1xuICAgICAgICBsb2dFcnJvcihrZXlQYXRoLCBlcnJvclByZWZpeCArIGAnIGNvbnRhaW5zIGludmFsaWQga2V5cyAnJHtpbnZhbGlkS2V5cy5qb2luKFwiJywgJ1wiKX0nYCk7XG4gICAgfVxuICAgIGlmIChjb25maWcuYWRkKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShjb25maWcuYWRkKSB8fCAhY29uZmlnLmFkZC5ldmVyeSgobik9PnR5cGVvZiBuID09PSAnc3RyaW5nJykpIHtcbiAgICAgICAgICAgIGxvZ0Vycm9yKGtleVBhdGgsIGVycm9yUHJlZml4ICsgYC5hZGQnIGlzIGludmFsaWQuIE11c3QgYmUgYW4gYXJyYXkgb2Ygc3RyaW5ncyAoZXh0ZW5zaW9uIElEcylgKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBpZiAoY29uZmlnLnJlbW92ZSkge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkoY29uZmlnLnJlbW92ZSkgfHwgIWNvbmZpZy5yZW1vdmUuZXZlcnkoKG4pPT50eXBlb2YgbiA9PT0gJ3N0cmluZycpKSB7XG4gICAgICAgICAgICBsb2dFcnJvcihrZXlQYXRoLCBlcnJvclByZWZpeCArIGAucmVtb3ZlJyBpcyBpbnZhbGlkLiBNdXN0IGJlIGFuIGFycmF5IG9mIHN0cmluZ3MgKGV4dGVuc2lvbiBJRHMpYCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgaWYgKGNvbmZpZy5vcmRlcikge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkoY29uZmlnLm9yZGVyKSB8fCAhY29uZmlnLm9yZGVyLmV2ZXJ5KChuKT0+dHlwZW9mIG4gPT09ICdzdHJpbmcnKSkge1xuICAgICAgICAgICAgbG9nRXJyb3Ioa2V5UGF0aCwgZXJyb3JQcmVmaXggKyBgLm9yZGVyJyBpcyBpbnZhbGlkLiBNdXN0IGJlIGFuIGFycmF5IG9mIHN0cmluZ3MgKGV4dGVuc2lvbiBJRHMpYCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgaWYgKGNvbmZpZy5jb25maWd1cmUpIHtcbiAgICAgICAgaWYgKCFpc09yZGluYXJ5T2JqZWN0KGNvbmZpZy5jb25maWd1cmUpKSB7XG4gICAgICAgICAgICBsb2dFcnJvcihrZXlQYXRoLCBlcnJvclByZWZpeCArIGAuY29uZmlndXJlJyBpcyBpbnZhbGlkLiBNdXN0IGJlIGFuIG9iamVjdCB3aXRoIGV4dGVuc2lvbiBJRHMgZm9yIGtleXNgKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbmZ1bmN0aW9uIGdldFByb3ZpZGVkQ29uZmlncyhjb25maWdTdGF0ZSwgdGVtcENvbmZpZ1N0YXRlKSB7XG4gICAgcmV0dXJuIFtcbiAgICAgICAgLi4uY29uZmlnU3RhdGUucHJvdmlkZWRDb25maWdzLm1hcCgoYyk9PmMuY29uZmlnKSxcbiAgICAgICAgdGVtcENvbmZpZ1N0YXRlLmNvbmZpZ1xuICAgIF07XG59XG4vKipcbiAqIFZhbGlkYXRlcyB0aGUgY29uZmlnIHNjaGVtYSBmb3IgYSBtb2R1bGUuIFNpbmNlIHByb2JsZW1zIGlkZW50aWZpZWQgaGVyZSBhcmUgcHJvZ3JhbW1pbmcgZXJyb3JzXG4gKiB0aGF0IGhvcGVmdWxseSB3aWxsIGJlIGNhdWdodCBkdXJpbmcgZGV2ZWxvcG1lbnQsIHRoaXMgZnVuY3Rpb24gbG9ncyBlcnJvcnMgdG8gdGhlIGNvbnNvbGUgZGlyZWN0bHk7XG4gKiBpdCdzIGZpbmUgaWYgd2Ugc3BhbSB0aGUgdXNlciB3aXRoIHRoZXNlIGVycm9ycy5cbiAqLyBmdW5jdGlvbiB2YWxpZGF0ZUNvbmZpZ1NjaGVtYShtb2R1bGVOYW1lLCBzY2hlbWEsIGtleVBhdGggPSAnJykge1xuICAgIGNvbnN0IHVwZGF0ZU1lc3NhZ2UgPSBgUGxlYXNlIHZlcmlmeSB0aGF0IHlvdSBhcmUgcnVubmluZyB0aGUgbGF0ZXN0IHZlcnNpb24gYW5kLCBpZiBzbywgYWxlcnQgdGhlIG1haW50YWluZXIuYDtcbiAgICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyhzY2hlbWEpLmZpbHRlcigoayk9PiFrLnN0YXJ0c1dpdGgoJ18nKSkpe1xuICAgICAgICBjb25zdCB0aGlzS2V5UGF0aCA9IGtleVBhdGggKyAoa2V5UGF0aCAmJiAnLicpICsga2V5O1xuICAgICAgICBjb25zdCBzY2hlbWFQYXJ0ID0gc2NoZW1hW2tleV07XG4gICAgICAgIGlmICh0aGlzS2V5UGF0aCA9PT0gJ0Rpc3BsYXkgY29uZGl0aW9ucycpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYCR7bW9kdWxlTmFtZX0gZGVjbGFyZXMgYSBjb25maWd1cmF0aW9uIG9wdGlvbiBjYWxsZWQgXCJEaXNwbGF5IGNvbmRpdGlvbnNcIjsgdGhlIFwiRGlzcGxheSBjb25kaXRpb25zXCIgb3B0aW9uIGlzIGEgcmVzZXJ2ZWQgbmFtZS4gJHt1cGRhdGVNZXNzYWdlfWApO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzS2V5UGF0aCA9PT0gJ1RyYW5zbGF0aW9uIG92ZXJyaWRlcycpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYCR7bW9kdWxlTmFtZX0gZGVjbGFyZXMgYSBjb25maWd1cmF0aW9uIG9wdGlvbiBjYWxsZWQgXCJUcmFuc2xhdGlvbiBvdmVycmlkZXNcIjsgdGhlIFwiVHJhbnNsYXRpb24gb3ZlcnJpZGVzXCIgb3B0aW9uIGlzIGEgcmVzZXJ2ZWQgbmFtZS4gJHt1cGRhdGVNZXNzYWdlfWApO1xuICAgICAgICB9XG4gICAgICAgIGlmICghaXNPcmRpbmFyeU9iamVjdChzY2hlbWFQYXJ0KSkge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcihgJHttb2R1bGVOYW1lfSBoYXMgYmFkIGNvbmZpZyBzY2hlbWEgZGVmaW5pdGlvbiBmb3Iga2V5ICcke3RoaXNLZXlQYXRofScuICR7dXBkYXRlTWVzc2FnZX1gKTtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIGlmICghc2NoZW1hUGFydC5oYXNPd25Qcm9wZXJ0eSgnX2RlZmF1bHQnKSkge1xuICAgICAgICAgICAgLy8gcmVjdXJzZSBmb3IgbmVzdGVkIGNvbmZpZyBrZXlzXG4gICAgICAgICAgICB2YWxpZGF0ZUNvbmZpZ1NjaGVtYShtb2R1bGVOYW1lLCBzY2hlbWFQYXJ0LCB0aGlzS2V5UGF0aCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgZWxlbWVudHMgPSBzY2hlbWFQYXJ0Ll9lbGVtZW50cztcbiAgICAgICAgaWYgKGhhc09iamVjdFNjaGVtYShlbGVtZW50cykpIHtcbiAgICAgICAgICAgIHZhbGlkYXRlQ29uZmlnU2NoZW1hKG1vZHVsZU5hbWUsIGVsZW1lbnRzLCB0aGlzS2V5UGF0aCArICcuX2VsZW1lbnRzJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHNjaGVtYVBhcnQuX3ZhbGlkYXRvcnMpIHtcbiAgICAgICAgICAgIGZvciAobGV0IHZhbGlkYXRvciBvZiBzY2hlbWFQYXJ0Ll92YWxpZGF0b3JzKXtcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHZhbGlkYXRvciAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKGAke21vZHVsZU5hbWV9IGhhcyBpbnZhbGlkIHZhbGlkYXRvciBmb3Iga2V5ICcke3RoaXNLZXlQYXRofScgJHt1cGRhdGVNZXNzYWdlfS5gICsgYFxcblxcbklmIHlvdSdyZSB0aGUgbWFpbnRhaW5lcjogdmFsaWRhdG9ycyBtdXN0IGJlIGZ1bmN0aW9ucyB0aGF0IHJldHVybiBlaXRoZXIgYCArIGB1bmRlZmluZWQgb3IgYW4gZXJyb3Igc3RyaW5nLiBSZWNlaXZlZCAke3ZhbGlkYXRvcn0uYCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHZhbHVlVHlwZSA9IHNjaGVtYVBhcnQuX3R5cGU7XG4gICAgICAgIGlmICh2YWx1ZVR5cGUgJiYgIU9iamVjdC52YWx1ZXMoVHlwZSkuaW5jbHVkZXModmFsdWVUeXBlKSkge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcihgJHttb2R1bGVOYW1lfSBoYXMgaW52YWxpZCB0eXBlIGZvciBrZXkgJyR7dGhpc0tleVBhdGh9JyAke3VwZGF0ZU1lc3NhZ2V9LmAgKyBgXFxuXFxuSWYgeW91J3JlIHRoZSBtYWludGFpbmVyOiB0aGUgYWxsb3dlZCB0eXBlcyBhcmUgJHtPYmplY3QudmFsdWVzKFR5cGUpLmpvaW4oJywgJyl9LiBgICsgYFJlY2VpdmVkICcke3ZhbHVlVHlwZX0nYCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKE9iamVjdC5rZXlzKHNjaGVtYVBhcnQpLmV2ZXJ5KChrKT0+W1xuICAgICAgICAgICAgICAgICdfZGVzY3JpcHRpb24nLFxuICAgICAgICAgICAgICAgICdfdmFsaWRhdG9ycycsXG4gICAgICAgICAgICAgICAgJ19lbGVtZW50cycsXG4gICAgICAgICAgICAgICAgJ190eXBlJ1xuICAgICAgICAgICAgXS5pbmNsdWRlcyhrKSkgJiYgIWtleVBhdGguaW5jbHVkZXMoJy5fZWxlbWVudHMnKSkge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcihgJHttb2R1bGVOYW1lfSBoYXMgYmFkIGNvbmZpZyBzY2hlbWEgZGVmaW5pdGlvbiBmb3Iga2V5ICcke3RoaXNLZXlQYXRofScuICR7dXBkYXRlTWVzc2FnZX0uYCArIGBcXG5cXG5JZiB5b3UncmUgdGhlIG1haW50YWluZXI6IGFsbCBjb25maWcgZWxlbWVudHMgbXVzdCBoYXZlIGEgZGVmYXVsdC4gYCArIGBSZWNlaXZlZCAke0pTT04uc3RyaW5naWZ5KHNjaGVtYVBhcnQpfWApO1xuICAgICAgICB9XG4gICAgICAgIGlmIChlbGVtZW50cyAmJiB2YWx1ZVR5cGUgJiYgIVtcbiAgICAgICAgICAgIFR5cGUuQXJyYXksXG4gICAgICAgICAgICBUeXBlLk9iamVjdFxuICAgICAgICBdLmluY2x1ZGVzKHZhbHVlVHlwZSkpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYCR7bW9kdWxlTmFtZX0gaGFzIGJhZCBjb25maWcgc2NoZW1hIGRlZmluaXRpb24gZm9yIGtleSAnJHt0aGlzS2V5UGF0aH0nLiAke3VwZGF0ZU1lc3NhZ2V9LmAgKyBgXFxuXFxuSWYgeW91J3JlIHRoZSBtYWludGFpbmVyOiB0aGUgJ2VsZW1lbnRzJyBrZXkgb25seSB3b3JrcyB3aXRoICdfdHlwZScgZXF1YWwgdG8gJ0FycmF5JyBvciAnT2JqZWN0Jy4gYCArIGBSZWNlaXZlZCAke0pTT04uc3RyaW5naWZ5KHZhbHVlVHlwZSl9YCk7XG4gICAgICAgIH1cbiAgICB9XG59XG5mdW5jdGlvbiBnZXRDb25maWdGb3JNb2R1bGUobW9kdWxlTmFtZSwgY29uZmlnU3RhdGUsIHRlbXBDb25maWdTdGF0ZSkge1xuICAgIGNvbnN0IHNjaGVtYSA9IGNvbmZpZ1N0YXRlLnNjaGVtYXNbbW9kdWxlTmFtZV07XG4gICAgY29uc3QgaW5wdXRDb25maWcgPSBtZXJnZUNvbmZpZ3NGb3IobW9kdWxlTmFtZSwgZ2V0UHJvdmlkZWRDb25maWdzKGNvbmZpZ1N0YXRlLCB0ZW1wQ29uZmlnU3RhdGUpKTtcbiAgICB2YWxpZGF0ZVN0cnVjdHVyZShzY2hlbWEsIGlucHV0Q29uZmlnLCBtb2R1bGVOYW1lKTtcbiAgICBjb25zdCBjb25maWcgPSBzZXREZWZhdWx0cyhzY2hlbWEsIGlucHV0Q29uZmlnKTtcbiAgICBydW5BbGxWYWxpZGF0b3JzSW5Db25maWdUcmVlKHNjaGVtYSwgY29uZmlnLCBtb2R1bGVOYW1lKTtcbiAgICBkZWxldGUgY29uZmlnLmV4dGVuc2lvblNsb3RzO1xuICAgIHJldHVybiBjb25maWc7XG59XG5mdW5jdGlvbiBnZXRDb25maWdGb3JNb2R1bGVJbXBsaWNpdFNjaGVtYShtb2R1bGVOYW1lLCBjb25maWdTdGF0ZSwgdGVtcENvbmZpZ1N0YXRlKSB7XG4gICAgY29uc3QgaW5wdXRDb25maWcgPSBtZXJnZUNvbmZpZ3NGb3IobW9kdWxlTmFtZSwgZ2V0UHJvdmlkZWRDb25maWdzKGNvbmZpZ1N0YXRlLCB0ZW1wQ29uZmlnU3RhdGUpKTtcbiAgICBjb25zdCBjb25maWcgPSBzZXREZWZhdWx0cyhpbXBsaWNpdENvbmZpZ1NjaGVtYSwgaW5wdXRDb25maWcpO1xuICAgIHJ1bkFsbFZhbGlkYXRvcnNJbkNvbmZpZ1RyZWUoaW1wbGljaXRDb25maWdTY2hlbWEsIGNvbmZpZywgbW9kdWxlTmFtZSk7XG4gICAgZGVsZXRlIGNvbmZpZy5leHRlbnNpb25TbG90cztcbiAgICByZXR1cm4gY29uZmlnO1xufVxuZnVuY3Rpb24gbWVyZ2VDb25maWdzRm9yKG1vZHVsZU5hbWUsIGFsbENvbmZpZ3MpIHtcbiAgICBjb25zdCBhbGxDb25maWdzRm9yTW9kdWxlID0gYWxsQ29uZmlncy5tYXAoKHsgW21vZHVsZU5hbWVdOiBjIH0pPT5jKS5maWx0ZXIoKGMpPT4hIWMpO1xuICAgIHJldHVybiBtZXJnZUNvbmZpZ3MoYWxsQ29uZmlnc0Zvck1vZHVsZSk7XG59XG5mdW5jdGlvbiBtZXJnZUNvbmZpZ3MoY29uZmlncykge1xuICAgIGNvbnN0IG1lcmdlRGVlcEFsbCA9IHJlZHVjZShtZXJnZURlZXBSaWdodCk7XG4gICAgcmV0dXJuIG1lcmdlRGVlcEFsbCh7fSwgY29uZmlncyk7XG59XG4vKipcbiAqIFJlY3Vyc2l2ZWx5IGNoZWNrIHRoZSBwcm92aWRlZCBjb25maWcgdHJlZSB0byBtYWtlIHN1cmUgdGhhdCBhbGxcbiAqIG9mIHRoZSBwcm92aWRlZCBwcm9wZXJ0aWVzIGV4aXN0IGluIHRoZSBzY2hlbWEsIGFuZCB0aGF0IHR5cGVzIGFyZVxuICogY29ycmVjdC4gRG9lcyBub3QgcnVuIHZhbGlkYXRvcnMgeWV0LCBzaW5jZSB0aG9zZSB3aWxsIGJlIHJ1biBvblxuICogdGhlIGNvbmZpZyB3aXRoIHRoZSBkZWZhdWx0cyBmaWxsZWQgaW4uXG4gKi8gZnVuY3Rpb24gdmFsaWRhdGVTdHJ1Y3R1cmUoc2NoZW1hLCBjb25maWcsIGtleVBhdGggPSAnJykge1xuICAgIC8vIHZhbGlkYXRlIGVhY2ggY29uc3RpdHVlbnQgZWxlbWVudFxuICAgIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKGNvbmZpZykpe1xuICAgICAgICBjb25zdCB2YWx1ZSA9IGNvbmZpZ1trZXldO1xuICAgICAgICBjb25zdCB0aGlzS2V5UGF0aCA9IGtleVBhdGggKyAnLicgKyBrZXk7XG4gICAgICAgIGNvbnN0IHNjaGVtYVBhcnQgPSBzY2hlbWFba2V5XTtcbiAgICAgICAgaWYgKCFzY2hlbWEuaGFzT3duUHJvcGVydHkoa2V5KSkge1xuICAgICAgICAgICAgaWYgKCEoa2V5ID09PSAnZXh0ZW5zaW9uU2xvdHMnICYmIGtleVBhdGggIT09ICcnKSkge1xuICAgICAgICAgICAgICAgIGxvZ0Vycm9yKHRoaXNLZXlQYXRoLCBgVW5rbm93biBjb25maWcga2V5ICcke3RoaXNLZXlQYXRofScgcHJvdmlkZWQuIElnbm9yaW5nLmApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgdmFsaWRhdGVCcmFuY2hTdHJ1Y3R1cmUoc2NoZW1hUGFydCwgdmFsdWUsIHRoaXNLZXlQYXRoKTtcbiAgICB9XG59XG5mdW5jdGlvbiB2YWxpZGF0ZUJyYW5jaFN0cnVjdHVyZShzY2hlbWFQYXJ0LCB2YWx1ZSwga2V5UGF0aCkge1xuICAgIGNoZWNrVHlwZShrZXlQYXRoLCBzY2hlbWFQYXJ0Ll90eXBlLCB2YWx1ZSk7XG4gICAgaWYgKGlzT3JkaW5hcnlPYmplY3QodmFsdWUpKSB7XG4gICAgICAgIGlmIChzY2hlbWFQYXJ0Ll90eXBlID09PSBUeXBlLk9iamVjdCkge1xuICAgICAgICAgICAgLy8gdmFsaWRhdGUgYXMgZnJlZWZvcm0gb2JqZWN0XG4gICAgICAgICAgICB2YWxpZGF0ZUZyZWVmb3JtT2JqZWN0U3RydWN0dXJlKHNjaGVtYVBhcnQsIHZhbHVlLCBrZXlQYXRoKTtcbiAgICAgICAgfSBlbHNlIGlmICghKHNjaGVtYVBhcnQuaGFzT3duUHJvcGVydHkoJ19kZWZhdWx0JykgfHwgc2NoZW1hUGFydC5oYXNPd25Qcm9wZXJ0eSgnX3R5cGUnKSkpIHtcbiAgICAgICAgICAgIC8vIHZhbGlkYXRlIGFzIG5vcm1hbCBuZXN0ZWQgY29uZmlnXG4gICAgICAgICAgICB2YWxpZGF0ZVN0cnVjdHVyZShzY2hlbWFQYXJ0LCB2YWx1ZSwga2V5UGF0aCk7XG4gICAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgICBpZiAoc2NoZW1hUGFydC5fdHlwZSA9PT0gVHlwZS5BcnJheSkge1xuICAgICAgICAgICAgdmFsaWRhdGVBcnJheVN0cnVjdHVyZShzY2hlbWFQYXJ0LCB2YWx1ZSwga2V5UGF0aCk7XG4gICAgICAgIH1cbiAgICB9XG59XG5mdW5jdGlvbiB2YWxpZGF0ZUZyZWVmb3JtT2JqZWN0U3RydWN0dXJlKGZyZWVmb3JtT2JqZWN0U2NoZW1hLCBjb25maWcsIGtleVBhdGgpIHtcbiAgICBpZiAoZnJlZWZvcm1PYmplY3RTY2hlbWEuX2VsZW1lbnRzKSB7XG4gICAgICAgIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKGNvbmZpZykpe1xuICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBjb25maWdba2V5XTtcbiAgICAgICAgICAgIHZhbGlkYXRlQnJhbmNoU3RydWN0dXJlKGZyZWVmb3JtT2JqZWN0U2NoZW1hLl9lbGVtZW50cywgdmFsdWUsIGAke2tleVBhdGh9LiR7a2V5fWApO1xuICAgICAgICB9XG4gICAgfVxufVxuZnVuY3Rpb24gdmFsaWRhdGVBcnJheVN0cnVjdHVyZShhcnJheVNjaGVtYSwgdmFsdWUsIGtleVBhdGgpIHtcbiAgICBjb25zdCB2YWxpZGF0ZWRBc0FycmF5ID0gY2hlY2tUeXBlKGtleVBhdGgsIFR5cGUuQXJyYXksIHZhbHVlKTtcbiAgICBpZiAoIXZhbGlkYXRlZEFzQXJyYXkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICAvLyBpZiB0aGVyZSBpcyBhbiBhcnJheSBlbGVtZW50IG9iamVjdCBzY2hlbWEsIHZlcmlmeSB0aGF0IGVsZW1lbnRzIG1hdGNoIGl0XG4gICAgaWYgKGhhc09iamVjdFNjaGVtYShhcnJheVNjaGVtYS5fZWxlbWVudHMpKSB7XG4gICAgICAgIGZvcihsZXQgaSA9IDA7IGkgPCB2YWx1ZS5sZW5ndGg7IGkrKyl7XG4gICAgICAgICAgICB2YWxpZGF0ZUJyYW5jaFN0cnVjdHVyZShhcnJheVNjaGVtYS5fZWxlbWVudHMsIHZhbHVlW2ldLCBgJHtrZXlQYXRofVske2l9XWApO1xuICAgICAgICB9XG4gICAgfVxuICAgIGZvcihsZXQgaSA9IDA7IGkgPCB2YWx1ZS5sZW5ndGg7IGkrKyl7XG4gICAgICAgIGNoZWNrVHlwZShgJHtrZXlQYXRofVske2l9XWAsIGFycmF5U2NoZW1hLl9lbGVtZW50cz8uX3R5cGUsIHZhbHVlW2ldKTtcbiAgICB9XG59XG4vKipcbiAqIFJ1biBhbGwgdGhlIHZhbGlkYXRvcnMgaW4gdGhlIGNvbmZpZyB0cmVlLiBUaGlzIHNob3VsZCBiZSBydW5cbiAqIG9uIHRoZSBjb25maWcgb2JqZWN0IGFmdGVyIGl0IGhhcyBiZWVuIGZpbGxlZCBpbiB3aXRoIGFsbCB0aGUgZGVmYXVsdHMsIHNpbmNlXG4gKiBoaWdoZXItbGV2ZWwgdmFsaWRhdG9ycyBtYXkgcmVmZXIgdG8gZGVmYXVsdCB2YWx1ZXMuXG4gKi8gZnVuY3Rpb24gcnVuQWxsVmFsaWRhdG9yc0luQ29uZmlnVHJlZShzY2hlbWEsIGNvbmZpZywga2V5UGF0aCA9ICcnKSB7XG4gICAgLy8gSWYgYCFzY2hlbWFgLCB0aGVyZSBzaG91bGQgaGF2ZSBiZWVuIGEgc3RydWN0dXJhbCB2YWxpZGF0aW9uIGVycm9yIHByaW50ZWQgYWxyZWFkeS5cbiAgICBpZiAoc2NoZW1hKSB7XG4gICAgICAgIGlmIChjb25maWcgIT09IHNjaGVtYS5fZGVmYXVsdCkge1xuICAgICAgICAgICAgcnVuVmFsaWRhdG9ycyhrZXlQYXRoLCBzY2hlbWEuX3ZhbGlkYXRvcnMsIGNvbmZpZyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGlzT3JkaW5hcnlPYmplY3QoY29uZmlnKSkge1xuICAgICAgICAgICAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXMoY29uZmlnKSl7XG4gICAgICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBjb25maWdba2V5XTtcbiAgICAgICAgICAgICAgICBjb25zdCB0aGlzS2V5UGF0aCA9IGtleVBhdGggKyAnLicgKyBrZXk7XG4gICAgICAgICAgICAgICAgY29uc3Qgc2NoZW1hUGFydCA9IHNjaGVtYVtrZXldO1xuICAgICAgICAgICAgICAgIGlmIChzY2hlbWEuX3R5cGUgPT09IFR5cGUuT2JqZWN0ICYmIHNjaGVtYS5fZWxlbWVudHMpIHtcbiAgICAgICAgICAgICAgICAgICAgcnVuQWxsVmFsaWRhdG9yc0luQ29uZmlnVHJlZShzY2hlbWEuX2VsZW1lbnRzLCB2YWx1ZSwgdGhpc0tleVBhdGgpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHJ1bkFsbFZhbGlkYXRvcnNJbkNvbmZpZ1RyZWUoc2NoZW1hUGFydCwgdmFsdWUsIHRoaXNLZXlQYXRoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAoQXJyYXkuaXNBcnJheShjb25maWcpICYmIHNjaGVtYS5fZWxlbWVudHMpIHtcbiAgICAgICAgICAgIGZvcihsZXQgaSA9IDA7IGkgPCBjb25maWcubGVuZ3RoOyBpKyspe1xuICAgICAgICAgICAgICAgIHJ1bkFsbFZhbGlkYXRvcnNJbkNvbmZpZ1RyZWUoc2NoZW1hLl9lbGVtZW50cywgY29uZmlnW2ldLCBgJHtrZXlQYXRofVske2l9XWApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxufVxuLyoqXG4gKiBSdW4gdHlwZSB2YWxpZGF0aW9uIGZvciB0aGUgdmFsdWUsIGxvZ2dpbmcgYW55IGVycm9ycy5cbiAqIEByZXR1cm5zIHRydWUgaWYgdmFsaWRhdGlvbiBwYXNzZXMsIGZhbHNlIG90aGVyd2lzZVxuICovIGZ1bmN0aW9uIGNoZWNrVHlwZShrZXlQYXRoLCBfdHlwZSwgdmFsdWUpIHtcbiAgICBpZiAoX3R5cGUpIHtcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnNhZmUtZnVuY3Rpb24tdHlwZVxuICAgICAgICBjb25zdCB2YWxpZGF0b3IgPSB7XG4gICAgICAgICAgICBBcnJheTogaXNBcnJheSxcbiAgICAgICAgICAgIEJvb2xlYW46IGlzQm9vbGVhbixcbiAgICAgICAgICAgIENvbmNlcHRVdWlkOiBpc1V1aWQsXG4gICAgICAgICAgICBOdW1iZXI6IGlzTnVtYmVyLFxuICAgICAgICAgICAgT2JqZWN0OiBpc09iamVjdCxcbiAgICAgICAgICAgIFN0cmluZzogaXNTdHJpbmcsXG4gICAgICAgICAgICBVVUlEOiBpc1V1aWQsXG4gICAgICAgICAgICBQZXJzb25BdHRyaWJ1dGVUeXBlVXVpZDogaXNVdWlkLFxuICAgICAgICAgICAgUGF0aWVudElkZW50aWZpZXJUeXBlVXVpZDogaXNVdWlkXG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiBydW5WYWxpZGF0b3JzKGtleVBhdGgsIFtcbiAgICAgICAgICAgIHZhbGlkYXRvcltfdHlwZV1cbiAgICAgICAgXSwgdmFsdWUpO1xuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbn1cbi8qKlxuICogUnVucyB2YWxpZGF0b3JzLCBsb2dnaW5nIGVycm9ycy5cbiAqIEByZXR1cm5zIHRydWUgaWYgYWxsIHBhc3MsIGZhbHNlIG90aGVyd2lzZS5cbiAqLyAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVuc2FmZS1mdW5jdGlvbi10eXBlXG5mdW5jdGlvbiBydW5WYWxpZGF0b3JzKGtleVBhdGgsIHZhbGlkYXRvcnMsIHZhbHVlKSB7XG4gICAgbGV0IHJldHVyblZhbHVlID0gdHJ1ZTtcbiAgICBpZiAodmFsaWRhdG9ycykge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgZm9yIChsZXQgdmFsaWRhdG9yIG9mIHZhbGlkYXRvcnMpe1xuICAgICAgICAgICAgICAgIGNvbnN0IHZhbGlkYXRvclJlc3VsdCA9IHZhbGlkYXRvcih2YWx1ZSk7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiB2YWxpZGF0b3JSZXN1bHQgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG1lc3NhZ2UgPSB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnID8gYEludmFsaWQgY29uZmlndXJhdGlvbiBmb3IgJHtrZXlQYXRofTogJHt2YWxpZGF0b3JSZXN1bHR9YCA6IGBJbnZhbGlkIGNvbmZpZ3VyYXRpb24gdmFsdWUgJHt2YWx1ZX0gZm9yICR7a2V5UGF0aH06ICR7dmFsaWRhdG9yUmVzdWx0fWA7XG4gICAgICAgICAgICAgICAgICAgIGxvZ0Vycm9yKGtleVBhdGgsIG1lc3NhZ2UpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm5WYWx1ZSA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcihgU2tpcHBpbmcgaW52YWxpZCB2YWxpZGF0b3IgYXQgXCIke2tleVBhdGh9XCIuIEVuY291bnRlcmVkIGVycm9yXFxuXFx0JHtlfWApO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiByZXR1cm5WYWx1ZTtcbn1cbi8vIFJlY3Vyc2l2ZWx5IGZpbGwgaW4gdGhlIGNvbmZpZyB3aXRoIHZhbHVlcyBmcm9tIHRoZSBzY2hlbWEuXG5jb25zdCBzZXREZWZhdWx0cyA9IChzY2hlbWEsIGlucHV0Q29uZmlnKT0+e1xuICAgIGNvbnN0IGNvbmZpZyA9IGNsb25lKGlucHV0Q29uZmlnKTtcbiAgICBpZiAoIXNjaGVtYSkge1xuICAgICAgICByZXR1cm4gY29uZmlnO1xuICAgIH1cbiAgICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyhzY2hlbWEpKXtcbiAgICAgICAgY29uc3QgY29uZmlnUGFydCA9IGNvbmZpZ1trZXldO1xuICAgICAgICBjb25zdCBzY2hlbWFQYXJ0ID0gc2NoZW1hW2tleV07XG4gICAgICAgIC8vIFRoZSBgc2NoZW1hUGFydCAmJmAgY2xhdXNlIG9mIHRoaXMgYGlmYCBzdGF0ZW1lbnQgd2lsbCBvbmx5IGZhaWxcbiAgICAgICAgLy8gaWYgdGhlIHNjaGVtYSBpcyB2ZXJ5IGludmFsaWQuIEl0IGlzIHRoZXJlIHRvIHByZXZlbnQgdGhlIGFwcCBmcm9tXG4gICAgICAgIC8vIGNyYXNoaW5nIGNvbXBsZXRlbHksIHRob3VnaCBpdCB3aWxsIHByb2R1Y2UgdW5leHBlY3RlZCBiZWhhdmlvci5cbiAgICAgICAgLy8gSWYgdGhpcyBoYXBwZW5zLCB0aGVyZSBzaG91bGQgYmUgbGVnaWJsZSBlcnJvcnMgaW4gdGhlIGNvbnNvbGUgZnJvbVxuICAgICAgICAvLyB0aGUgc2NoZW1hIHZhbGlkYXRvci5cbiAgICAgICAgaWYgKHNjaGVtYVBhcnQgJiYgKHNjaGVtYVBhcnQuaGFzT3duUHJvcGVydHkoJ190eXBlJykgfHwgc2NoZW1hUGFydC5oYXNPd25Qcm9wZXJ0eSgnX2RlZmF1bHQnKSkpIHtcbiAgICAgICAgICAgIC8vIFdlIGFzc3VtZSB0aGF0IHNjaGVtYVBhcnQgZGVmaW5lcyBhIGNvbmZpZyB2YWx1ZSwgc2luY2UgaXQgaGFzXG4gICAgICAgICAgICAvLyBhIHByb3BlcnR5IGBfdHlwZWAgb3IgYF9kZWZhdWx0YC5cbiAgICAgICAgICAgIGlmICghY29uZmlnLmhhc093blByb3BlcnR5KGtleSkpIHtcbiAgICAgICAgICAgICAgICBjb25maWdba2V5XSA9IHNjaGVtYVBhcnRbJ19kZWZhdWx0J107XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBXZSBhbHNvIGNoZWNrIGlmIGl0IGlzIGFuIG9iamVjdCBvciBhcnJheSB3aXRoIG9iamVjdCBlbGVtZW50cywgaW4gd2hpY2ggY2FzZSB3ZSByZWN1cnNlXG4gICAgICAgICAgICBjb25zdCBlbGVtZW50cyA9IHNjaGVtYVBhcnQuX2VsZW1lbnRzO1xuICAgICAgICAgICAgaWYgKGNvbmZpZ1BhcnQgJiYgaGFzT2JqZWN0U2NoZW1hKGVsZW1lbnRzKSkge1xuICAgICAgICAgICAgICAgIGlmIChzY2hlbWFQYXJ0Ll90eXBlID09PSBUeXBlLkFycmF5ICYmIEFycmF5LmlzQXJyYXkoY29uZmlnUGFydCkpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgY29uZmlnV2l0aERlZmF1bHRzID0gY29uZmlnUGFydC5tYXAoKGNvbmYpPT5zZXREZWZhdWx0cyhlbGVtZW50cywgY29uZikpO1xuICAgICAgICAgICAgICAgICAgICBjb25maWdba2V5XSA9IGNvbmZpZ1dpdGhEZWZhdWx0cztcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHNjaGVtYVBhcnQuX3R5cGUgPT09IFR5cGUuT2JqZWN0KSB7XG4gICAgICAgICAgICAgICAgICAgIGZvciAobGV0IG9iamVjdEtleSBvZiBPYmplY3Qua2V5cyhjb25maWdQYXJ0KSl7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25maWdQYXJ0W29iamVjdEtleV0gPSBzZXREZWZhdWx0cyhlbGVtZW50cywgY29uZmlnUGFydFtvYmplY3RLZXldKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmIChpc09yZGluYXJ5T2JqZWN0KHNjaGVtYVBhcnQpKSB7XG4gICAgICAgICAgICAvLyBTaW5jZSBzY2hlbWFQYXJ0IGhhcyBubyBwcm9wZXJ0eSBcIl90eXBlXCIsIGlmIGl0J3MgYW4gb3JkaW5hcnkgb2JqZWN0XG4gICAgICAgICAgICAvLyAodW5saWtlLCBpbXBvcnRhbnRseSwgdGhlIHZhbGlkYXRvcnMgYXJyYXkpLCB3ZSBhc3N1bWUgaXQgaXMgYSBwYXJlbnQgY29uZmlnIHByb3BlcnR5LlxuICAgICAgICAgICAgLy8gV2UgcmVjdXJzZSB0byBjb25maWdba2V5XSBhbmQgc2NoZW1hW2tleV0uIERlZmF1bHQgY29uZmlnW2tleV0gdG8ge30uXG4gICAgICAgICAgICBjb25zdCBzZWxlY3RlZENvbmZpZ1BhcnQgPSBjb25maWdQYXJ0ID8/IHt9O1xuICAgICAgICAgICAgLy8gVGhlcmUgd2lsbCBoYXZlIGJlZW4gYSB2YWxpZGF0aW9uIGVycm9yIGFscmVhZHkgaWYgY29uZmlnUGFydCBpcyBub3QgYSBwbGFpbiBvYmplY3QuXG4gICAgICAgICAgICBpZiAoaXNPcmRpbmFyeU9iamVjdChzZWxlY3RlZENvbmZpZ1BhcnQpKSB7XG4gICAgICAgICAgICAgICAgY29uZmlnW2tleV0gPSBzZXREZWZhdWx0cyhzY2hlbWFQYXJ0LCBzZWxlY3RlZENvbmZpZ1BhcnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBjb25maWc7XG59O1xuZnVuY3Rpb24gaGFzT2JqZWN0U2NoZW1hKGVsZW1lbnRzU2NoZW1hKSB7XG4gICAgcmV0dXJuICEhZWxlbWVudHNTY2hlbWEgJiYgT2JqZWN0LmtleXMoZWxlbWVudHNTY2hlbWEpLmZpbHRlcigoZSk9PiFbXG4gICAgICAgICAgICAnX2RlZmF1bHQnLFxuICAgICAgICAgICAgJ192YWxpZGF0b3JzJ1xuICAgICAgICBdLmluY2x1ZGVzKGUpKS5sZW5ndGggPiAwO1xufVxuZnVuY3Rpb24gaXNPcmRpbmFyeU9iamVjdCh2YWx1ZSkge1xuICAgIHJldHVybiB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmICFBcnJheS5pc0FycmF5KHZhbHVlKSAmJiB2YWx1ZSAhPT0gbnVsbDtcbn1cbi8qKiBLZWVwIHRyYWNrIG9mIHdoaWNoIHZhbGlkYXRpb24gZXJyb3JzIHdlIGhhdmUgZGlzcGxheWVkLiBFYWNoIG9uZSBzaG91bGQgb25seSBiZSBkaXNwbGF5ZWQgb25jZS4gKi8gbGV0IGRpc3BsYXllZFZhbGlkYXRpb25NZXNzYWdlcyA9IG5ldyBTZXQoKTtcbmZ1bmN0aW9uIGxvZ0Vycm9yKGtleVBhdGgsIG1lc3NhZ2UpIHtcbiAgICBjb25zdCBrZXkgPSBgJHtrZXlQYXRofTo6OiR7bWVzc2FnZX1gO1xuICAgIC8vIHRlY2huaWNhbGx5LCB0aGlzIHNob3VsZCBub3QgYmUgcG9zc2libGUsIGJ1dCBiZWNhdXNlIG9mIGhvdyB0aGluZ3Mgd2luZC11cCB0cmFuc3BpbGVkLCB0aGlzIGlzbid0IGltcG9zc2libGVcbiAgICBpZiAoIWRpc3BsYXllZFZhbGlkYXRpb25NZXNzYWdlcykge1xuICAgICAgICBkaXNwbGF5ZWRWYWxpZGF0aW9uTWVzc2FnZXMgPSBuZXcgU2V0KCk7XG4gICAgfVxuICAgIGlmICghZGlzcGxheWVkVmFsaWRhdGlvbk1lc3NhZ2VzLmhhcyhrZXkpKSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IobWVzc2FnZSk7XG4gICAgICAgIGRpc3BsYXllZFZhbGlkYXRpb25NZXNzYWdlcy5hZGQoa2V5KTtcbiAgICB9XG59XG4vKipcbiAqIE5vcm1hbGx5LCBjb25maWd1cmF0aW9uIGVycm9ycyBhcmUgb25seSBkaXNwbGF5ZWQgb25jZS4gVGhpcyBmdW5jdGlvbiBjbGVhcnMgdGhlIGxpc3Qgb2ZcbiAqIGRpc3BsYXllZCBlcnJvcnMsIHNvIHRoYXQgdGhleSB3aWxsIGJlIGRpc3BsYXllZCBhZ2Fpbi5cbiAqXG4gKiBAaW50ZXJuYWxcbiAqLyBleHBvcnQgZnVuY3Rpb24gY2xlYXJDb25maWdFcnJvcnMoa2V5UGF0aCkge1xuICAgIGlmIChrZXlQYXRoKSB7XG4gICAgICAgIGRpc3BsYXllZFZhbGlkYXRpb25NZXNzYWdlcy5mb3JFYWNoKChrZXkpPT57XG4gICAgICAgICAgICBpZiAoa2V5LnN0YXJ0c1dpdGgoa2V5UGF0aCkpIHtcbiAgICAgICAgICAgICAgICBkaXNwbGF5ZWRWYWxpZGF0aW9uTWVzc2FnZXMuZGVsZXRlKGtleSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIGRpc3BsYXllZFZhbGlkYXRpb25NZXNzYWdlcy5jbGVhcigpO1xuICAgIH1cbn1cbi8qKlxuICogQ2xlYW5zIHVwIGFsbCBjb25maWcgc3RvcmUgc3Vic2NyaXB0aW9ucyBhbmQgcmUtZXN0YWJsaXNoZXMgdGhlbS4gVGhpcyBpcyBwcmltYXJpbHlcbiAqIHVzZWZ1bCBmb3IgdGVzdGluZywgd2hlcmUgc3Vic2NyaXB0aW9ucyBzZXQgdXAgYXQgbW9kdWxlIGxvYWQgdGltZSBuZWVkIHRvIGJlIGNsZWFyZWRcbiAqIGJldHdlZW4gdGVzdHMgdG8gcHJldmVudCBpbmZpbml0ZSB1cGRhdGUgbG9vcHMuIEFmdGVyIGNsZWFyaW5nLCBzdWJzY3JpcHRpb25zIGFyZVxuICogcmUtZXN0YWJsaXNoZWQgc28gdGhlIGNvbmZpZyBzeXN0ZW0gY29udGludWVzIHRvIHdvcmsgbm9ybWFsbHkuXG4gKlxuICogQGludGVybmFsXG4gKi8gZXhwb3J0IGZ1bmN0aW9uIHJlc2V0Q29uZmlnU3lzdGVtKCkge1xuICAgIGNvbmZpZ1N1YnNjcmlwdGlvbnMuZm9yRWFjaCgodW5zdWJzY3JpYmUpPT51bnN1YnNjcmliZSgpKTtcbiAgICBjb25maWdTdWJzY3JpcHRpb25zLmxlbmd0aCA9IDA7XG4gICAgc2V0dXBDb25maWdTdWJzY3JpcHRpb25zKCk7XG59XG4vKipcbiAqIENvcGllZCBvdmVyIGZyb20gZXNtLWV4dGVuc2lvbnMuIEl0IHJpZ2h0bHkgYmVsb25ncyB0byB0aGF0IG1vZHVsZSwgYnV0IGVzbS1jb25maWdcbiAqIGNhbm5vdCBkZXBlbmQgb24gZXNtLWV4dGVuc2lvbnMuXG4gKi8gZnVuY3Rpb24gZ2V0RXh0ZW5zaW9uTmFtZUZyb21JZChleHRlbnNpb25JZCkge1xuICAgIGNvbnN0IFtleHRlbnNpb25OYW1lXSA9IGV4dGVuc2lvbklkLnNwbGl0KCcjJyk7XG4gICAgcmV0dXJuIGV4dGVuc2lvbk5hbWU7XG59XG4vKipcbiAqIFRoZSB0cmFuc2xhdGlvbiBvdmVycmlkZXMgc2NoZW1hIGlzIHVzZWQgaW4gdGhlIGltcGxpY2l0IHNjaGVtYSBnaXZlbiB0byBldmVyeSBtb2R1bGU7XG4gKiBwbHVzIGFueSBhZGRpdGlvbmFsIHRyYW5zbGF0aW9uIG5hbWVzcGFjZXMgKGF0IHRpbWUgb2Ygd3JpdGluZywgdGhpcyBpcyBqdXN0ICdjb3JlJykuXG4gKi8gY29uc3QgdHJhbnNsYXRpb25PdmVycmlkZXNTY2hlbWEgPSB7XG4gICAgJ1RyYW5zbGF0aW9uIG92ZXJyaWRlcyc6IHtcbiAgICAgICAgX2Rlc2NyaXB0aW9uOiAnUGVyLWxhbmd1YWdlIG92ZXJyaWRlcyBmb3IgZnJvbnRlbmQgdHJhbnNsYXRpb25zIHNob3VsZCBiZSBrZXllZCBieSBsYW5ndWFnZSBjb2RlIGFuZCBlYWNoIGxhbmd1YWdlIGRpY3Rpb25hcnkgY29udGFpbnMgdGhlIHRyYW5zbGF0aW9uIGtleSBhbmQgdGhlIGRpc3BsYXkgdmFsdWUnLFxuICAgICAgICBfdHlwZTogVHlwZS5PYmplY3QsXG4gICAgICAgIF9kZWZhdWx0OiB7fSxcbiAgICAgICAgX3ZhbGlkYXRvcnM6IFtcbiAgICAgICAgICAgIHZhbGlkYXRvcigobyk9Pk9iamVjdC5rZXlzKG8pLmV2ZXJ5KChrKT0+L15bYS16XXsyLDN9KC1bQS1aXXsyLDN9KT8kLy50ZXN0KGspKSwgKG8pPT57XG4gICAgICAgICAgICAgICAgY29uc3QgYmFkS2V5cyA9IE9iamVjdC5rZXlzKG8pLmZpbHRlcigoayk9PiEvXlthLXpdezIsM30oLVtBLVpdezIsM30pPyQvLnRlc3QoaykpO1xuICAgICAgICAgICAgICAgIHJldHVybiBgVGhlICdUcmFuc2xhdGlvbiBvdmVycmlkZXMnIG9iamVjdCBzaG91bGQgaGF2ZSBsYW5ndWFnZSBjb2RlcyBmb3Iga2V5cy4gTGFuZ3VhZ2UgY29kZXMgbXVzdCBiZSBpbiB0aGUgZm9ybSBvZiBhIHR3by10by10aHJlZSBsZXR0ZXIgbGFuZ3VhZ2UgY29kZSBvcHRpb25hbGx5IGZvbGxvd2VkIGJ5IGEgaHlwaGVuIGFuZCBhIHR3by10by10aHJlZSBsZXR0ZXIgY291bnRyeSBjb2RlLiBUaGUgZm9sbG93aW5nIGtleXMgZG8gbm90IGNvbmZvcm06ICR7YmFkS2V5cy5qb2luKCcsICcpfS5gO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgXVxuICAgIH1cbn07XG4vKipcbiAqIFRoZSBpbXBsaWNpdENvbmZpZ1NjaGVtYSBpcyBpbXBsaWNpdGx5IGluY2x1ZGVkIGluIGV2ZXJ5IGNvbmZpZ3VyYXRpb24gc2NoZW1hXG4gKi8gY29uc3QgaW1wbGljaXRDb25maWdTY2hlbWEgPSB7XG4gICAgJ0Rpc3BsYXkgY29uZGl0aW9ucyc6IHtcbiAgICAgICAgcHJpdmlsZWdlczoge1xuICAgICAgICAgICAgX2Rlc2NyaXB0aW9uOiAnVGhlIHByaXZpbGVnZShzKSB0aGUgdXNlciBtdXN0IGhhdmUgdG8gdXNlIHRoaXMgZXh0ZW5zaW9uJyxcbiAgICAgICAgICAgIF90eXBlOiBUeXBlLkFycmF5LFxuICAgICAgICAgICAgX2RlZmF1bHQ6IFtdXG4gICAgICAgIH0sXG4gICAgICAgIGV4cHJlc3Npb246IHtcbiAgICAgICAgICAgIF9kZXNjcmlwdGlvbjogJ1RoZSBleHByZXNzaW9uIHRoYXQgZGV0ZXJtaW5lcyB3aGV0aGVyIHRoZSBleHRlbnNpb24gaXMgZGlzcGxheWVkJyxcbiAgICAgICAgICAgIF90eXBlOiBUeXBlLlN0cmluZyxcbiAgICAgICAgICAgIF9kZWZhdWx0OiB1bmRlZmluZWRcbiAgICAgICAgfVxuICAgIH0sXG4gICAgLi4udHJhbnNsYXRpb25PdmVycmlkZXNTY2hlbWFcbn07XG4iXSwibmFtZXMiOlsiY2xvbmUiLCJlcXVhbHMiLCJyZWR1Y2UiLCJtZXJnZURlZXBSaWdodCIsIm9taXQiLCJUeXBlIiwiaXNBcnJheSIsImlzQm9vbGVhbiIsImlzVXVpZCIsImlzTnVtYmVyIiwiaXNPYmplY3QiLCJpc1N0cmluZyIsInZhbGlkYXRvciIsImNvbmZpZ0V4dGVuc2lvblN0b3JlIiwiY29uZmlnSW50ZXJuYWxTdG9yZSIsImdldENvbmZpZ1N0b3JlIiwiZ2V0RXh0ZW5zaW9uQ29uZmlnIiwiZ2V0RXh0ZW5zaW9uU2xvdHNDb25maWdTdG9yZSIsImdldEV4dGVuc2lvbnNDb25maWdTdG9yZSIsImltcGxlbWVudGVyVG9vbHNDb25maWdTdG9yZSIsInRlbXBvcmFyeUNvbmZpZ1N0b3JlIiwiY29uZmlnU3Vic2NyaXB0aW9ucyIsInJlY29tcHV0ZUFsbENvbmZpZ3MiLCJjb25maWdTdGF0ZSIsImdldFN0YXRlIiwidGVtcENvbmZpZ1N0YXRlIiwiZXh0ZW5zaW9uU3RhdGUiLCJjb21wdXRlTW9kdWxlQ29uZmlnIiwiY29tcHV0ZUltcGxlbWVudGVyVG9vbHNDb25maWciLCJjb21wdXRlRXh0ZW5zaW9uU2xvdENvbmZpZ3MiLCJjb21wdXRlRXh0ZW5zaW9uQ29uZmlncyIsInNldHVwQ29uZmlnU3Vic2NyaXB0aW9ucyIsInB1c2giLCJzdWJzY3JpYmUiLCJzdGF0ZSIsInRlbXBTdGF0ZSIsIm1vZHVsZU5hbWUiLCJPYmplY3QiLCJrZXlzIiwic2NoZW1hcyIsIm1vZHVsZVN0b3JlIiwibmV3U3RhdGUiLCJtb2R1bGVMb2FkZWQiLCJjb25maWciLCJnZXRDb25maWdGb3JNb2R1bGUiLCJ0cmFuc2xhdGlvbk92ZXJyaWRlc0xvYWRlZCIsImxvYWRlZCIsImdldENvbmZpZ0Zvck1vZHVsZUltcGxpY2l0U2NoZW1hIiwic2V0U3RhdGUiLCJzbG90Q29uZmlncyIsImdldEV4dGVuc2lvblNsb3RDb25maWdzIiwibmV3U2xvdFN0b3JlRW50cmllcyIsImZyb21FbnRyaWVzIiwiZW50cmllcyIsIm1hcCIsInNsb3ROYW1lIiwic2xvdFN0b3JlIiwib2xkU3RhdGUiLCJzbG90cyIsImdldEltcGxlbWVudGVyVG9vbHNDb25maWciLCJjb25maWdzIiwiZXh0ZW5zaW9uIiwibW91bnRlZEV4dGVuc2lvbnMiLCJjb21wdXRlRXh0ZW5zaW9uQ29uZmlnIiwic2xvdE1vZHVsZU5hbWUiLCJleHRlbnNpb25Nb2R1bGVOYW1lIiwiZXh0ZW5zaW9uSWQiLCJleHRlbnNpb25zQ29uZmlnU3RvcmUiLCJkZWZpbmVDb25maWdTY2hlbWEiLCJzY2hlbWEiLCJ2YWxpZGF0ZUNvbmZpZ1NjaGVtYSIsImVuaGFuY2VkU2NoZW1hIiwiaW1wbGljaXRDb25maWdTY2hlbWEiLCJyZWdpc3Rlck1vZHVsZVdpdGhDb25maWdTeXN0ZW0iLCJyZWdpc3Rlck1vZHVsZUxvYWQiLCJyZWdpc3RlclRyYW5zbGF0aW9uTmFtZXNwYWNlIiwibmFtZXNwYWNlIiwidHJhbnNsYXRpb25PdmVycmlkZXNTY2hlbWEiLCJkZWZpbmVFeHRlbnNpb25Db25maWdTY2hlbWEiLCJleHRlbnNpb25OYW1lIiwiY29uc29sZSIsImVycm9yIiwicHJvdmlkZSIsInNvdXJjZU5hbWUiLCJwcm92aWRlZENvbmZpZ3MiLCJzb3VyY2UiLCJnZXRDb25maWciLCJQcm9taXNlIiwicmVzb2x2ZSIsInN0b3JlIiwidXBkYXRlIiwidW5zdWJzY3JpYmUiLCJnZXRUcmFuc2xhdGlvbk92ZXJyaWRlcyIsInByb21pc2VzIiwiY29uZmlnU3RvcmUiLCJ0cmFuc2xhdGlvbk92ZXJyaWRlcyIsImFsbCIsInByb2Nlc3NDb25maWciLCJwcm92aWRlZENvbmZpZyIsImtleVBhdGhDb250ZXh0IiwidmFsaWRhdGVTdHJ1Y3R1cmUiLCJzZXREZWZhdWx0cyIsInJ1bkFsbFZhbGlkYXRvcnNJbkNvbmZpZ1RyZWUiLCJnZXRFeHRlbnNpb25OYW1lRnJvbUlkIiwiZXh0ZW5zaW9uQ29uZmlnU2NoZW1hIiwibmFtZU9mU2NoZW1hU291cmNlIiwiZ2V0UHJvdmlkZWRDb25maWdzIiwic2xvdE1vZHVsZUNvbmZpZyIsIm1lcmdlQ29uZmlnc0ZvciIsImNvbmZpZ092ZXJyaWRlIiwiZXh0ZW5zaW9uU2xvdHMiLCJjb25maWd1cmUiLCJleHRlbnNpb25Db25maWciLCJjb21iaW5lZENvbmZpZyIsIm1lcmdlQ29uZmlncyIsInJlc3VsdCIsImdldFNjaGVtYVdpdGhWYWx1ZXNBbmRTb3VyY2VzIiwiY29uZmlnc0FuZFNvdXJjZXMiLCJjIiwiY3JlYXRlVmFsdWVzQW5kU291cmNlc1RyZWUiLCJoYXNPd25Qcm9wZXJ0eSIsIl92YWx1ZSIsIl9kZWZhdWx0IiwiX3NvdXJjZSIsImlzT3JkaW5hcnlPYmplY3QiLCJvYmoiLCJrZXkiLCJhbGxDb25maWdzIiwic2xvdENvbmZpZ1Blck1vZHVsZSIsInZhbGlkYXRlQWxsRXh0ZW5zaW9uU2xvdENvbmZpZ3MiLCJjb25maWdCeVNsb3ROYW1lIiwidmFsaWRhdGVFeHRlbnNpb25TbG90Q29uZmlnIiwia2V5UGF0aCIsImVycm9yUHJlZml4IiwiaW52YWxpZEtleXMiLCJmaWx0ZXIiLCJrIiwiaW5jbHVkZXMiLCJsZW5ndGgiLCJsb2dFcnJvciIsImpvaW4iLCJhZGQiLCJBcnJheSIsImV2ZXJ5IiwibiIsInJlbW92ZSIsIm9yZGVyIiwidXBkYXRlTWVzc2FnZSIsInN0YXJ0c1dpdGgiLCJ0aGlzS2V5UGF0aCIsInNjaGVtYVBhcnQiLCJlbGVtZW50cyIsIl9lbGVtZW50cyIsImhhc09iamVjdFNjaGVtYSIsIl92YWxpZGF0b3JzIiwidmFsdWVUeXBlIiwiX3R5cGUiLCJ2YWx1ZXMiLCJKU09OIiwic3RyaW5naWZ5IiwiaW5wdXRDb25maWciLCJhbGxDb25maWdzRm9yTW9kdWxlIiwibWVyZ2VEZWVwQWxsIiwidmFsdWUiLCJ2YWxpZGF0ZUJyYW5jaFN0cnVjdHVyZSIsImNoZWNrVHlwZSIsInZhbGlkYXRlRnJlZWZvcm1PYmplY3RTdHJ1Y3R1cmUiLCJ2YWxpZGF0ZUFycmF5U3RydWN0dXJlIiwiZnJlZWZvcm1PYmplY3RTY2hlbWEiLCJhcnJheVNjaGVtYSIsInZhbGlkYXRlZEFzQXJyYXkiLCJpIiwicnVuVmFsaWRhdG9ycyIsIkJvb2xlYW4iLCJDb25jZXB0VXVpZCIsIk51bWJlciIsIlN0cmluZyIsIlVVSUQiLCJQZXJzb25BdHRyaWJ1dGVUeXBlVXVpZCIsIlBhdGllbnRJZGVudGlmaWVyVHlwZVV1aWQiLCJ2YWxpZGF0b3JzIiwicmV0dXJuVmFsdWUiLCJ2YWxpZGF0b3JSZXN1bHQiLCJtZXNzYWdlIiwiZSIsImNvbmZpZ1BhcnQiLCJjb25maWdXaXRoRGVmYXVsdHMiLCJjb25mIiwib2JqZWN0S2V5Iiwic2VsZWN0ZWRDb25maWdQYXJ0IiwiZWxlbWVudHNTY2hlbWEiLCJkaXNwbGF5ZWRWYWxpZGF0aW9uTWVzc2FnZXMiLCJTZXQiLCJoYXMiLCJjbGVhckNvbmZpZ0Vycm9ycyIsImZvckVhY2giLCJkZWxldGUiLCJjbGVhciIsInJlc2V0Q29uZmlnU3lzdGVtIiwic3BsaXQiLCJfZGVzY3JpcHRpb24iLCJvIiwidGVzdCIsImJhZEtleXMiLCJwcml2aWxlZ2VzIiwiZXhwcmVzc2lvbiIsInVuZGVmaW5lZCJdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///../../framework/esm-config/dist/module-config/module-config.js\n");
159
159
 
160
160
  /***/ }),
161
161
 
@@ -245,7 +245,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
245
245
  \********************************************************/
246
246
  /***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
247
247
 
248
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ fireOpenmrsEvent: () => (/* binding */ fireOpenmrsEvent),\n/* harmony export */ subscribeOpenmrsEvent: () => (/* binding */ subscribeOpenmrsEvent)\n/* harmony export */ });\n/**\n * Fires an OpenMRS custom event\n *\n * @param event The custom event to fire\n * @param payload The payload associated with this type of event\n * @returns true if the event was not cancelled and false, i.e., the result of `dispatchEvent()`\n */ function fireOpenmrsEvent(event, payload) {\n const evt = new CustomEvent(`openmrs:${event}`, {\n detail: payload ?? undefined,\n cancelable: true,\n bubbles: true\n });\n return window.dispatchEvent(evt);\n}\n/**\n * Subscribes to a custom OpenMRS event\n *\n * @param event The name of the event to listen to\n * @param handler The callback to be called when the event fires\n */ function subscribeOpenmrsEvent(event, handler) {\n const internalHandler = (event)=>{\n const detail = 'detail' in event && event.detail !== null ? event.detail : undefined;\n handler(detail);\n };\n window.addEventListener(`openmrs:${event}`, internalHandler);\n return ()=>{\n window.removeEventListener(`openmrs:${event}`, internalHandler);\n };\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi4vLi4vZnJhbWV3b3JrL2VzbS1lbXItYXBpL2Rpc3QvZXZlbnRzL2luZGV4LmpzIiwibWFwcGluZ3MiOiI7Ozs7O0FBQUE7Ozs7OztDQU1DLEdBQVUsU0FBU0EsaUJBQWlCQyxLQUFLLEVBQUVDLE9BQU87SUFDL0MsTUFBTUMsTUFBTSxJQUFJQyxZQUFZLENBQUMsUUFBUSxFQUFFSCxPQUFPLEVBQUU7UUFDNUNJLFFBQVFILFdBQVdJO1FBQ25CQyxZQUFZO1FBQ1pDLFNBQVM7SUFDYjtJQUNBLE9BQU9DLE9BQU9DLGFBQWEsQ0FBQ1A7QUFDaEM7QUFDQTs7Ozs7Q0FLQyxHQUFVLFNBQVNRLHNCQUFzQlYsS0FBSyxFQUFFVyxPQUFPO0lBQ3BELE1BQU1DLGtCQUFrQixDQUFDWjtRQUNyQixNQUFNSSxTQUFTLFlBQVlKLFNBQVNBLE1BQU1JLE1BQU0sS0FBSyxPQUFPSixNQUFNSSxNQUFNLEdBQUdDO1FBQzNFTSxRQUFRUDtJQUNaO0lBQ0FJLE9BQU9LLGdCQUFnQixDQUFDLENBQUMsUUFBUSxFQUFFYixPQUFPLEVBQUVZO0lBQzVDLE9BQU87UUFDSEosT0FBT00sbUJBQW1CLENBQUMsQ0FBQyxRQUFRLEVBQUVkLE9BQU8sRUFBRVk7SUFDbkQ7QUFDSiIsInNvdXJjZXMiOlsid2VicGFjazovL0BvcGVubXJzL2VzbS1hcHAtc2hlbGwvLi4vLi4vZnJhbWV3b3JrL2VzbS1lbXItYXBpL2Rpc3QvZXZlbnRzL2luZGV4LmpzPzI3OWMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBGaXJlcyBhbiBPcGVuTVJTIGN1c3RvbSBldmVudFxuICpcbiAqIEBwYXJhbSBldmVudCBUaGUgY3VzdG9tIGV2ZW50IHRvIGZpcmVcbiAqIEBwYXJhbSBwYXlsb2FkIFRoZSBwYXlsb2FkIGFzc29jaWF0ZWQgd2l0aCB0aGlzIHR5cGUgb2YgZXZlbnRcbiAqIEByZXR1cm5zIHRydWUgaWYgdGhlIGV2ZW50IHdhcyBub3QgY2FuY2VsbGVkIGFuZCBmYWxzZSwgaS5lLiwgdGhlIHJlc3VsdCBvZiBgZGlzcGF0Y2hFdmVudCgpYFxuICovIGV4cG9ydCBmdW5jdGlvbiBmaXJlT3Blbm1yc0V2ZW50KGV2ZW50LCBwYXlsb2FkKSB7XG4gICAgY29uc3QgZXZ0ID0gbmV3IEN1c3RvbUV2ZW50KGBvcGVubXJzOiR7ZXZlbnR9YCwge1xuICAgICAgICBkZXRhaWw6IHBheWxvYWQgPz8gdW5kZWZpbmVkLFxuICAgICAgICBjYW5jZWxhYmxlOiB0cnVlLFxuICAgICAgICBidWJibGVzOiB0cnVlXG4gICAgfSk7XG4gICAgcmV0dXJuIHdpbmRvdy5kaXNwYXRjaEV2ZW50KGV2dCk7XG59XG4vKipcbiAqIFN1YnNjcmliZXMgdG8gYSBjdXN0b20gT3Blbk1SUyBldmVudFxuICpcbiAqIEBwYXJhbSBldmVudCBUaGUgbmFtZSBvZiB0aGUgZXZlbnQgdG8gbGlzdGVuIHRvXG4gKiBAcGFyYW0gaGFuZGxlciBUaGUgY2FsbGJhY2sgdG8gYmUgY2FsbGVkIHdoZW4gdGhlIGV2ZW50IGZpcmVzXG4gKi8gZXhwb3J0IGZ1bmN0aW9uIHN1YnNjcmliZU9wZW5tcnNFdmVudChldmVudCwgaGFuZGxlcikge1xuICAgIGNvbnN0IGludGVybmFsSGFuZGxlciA9IChldmVudCk9PntcbiAgICAgICAgY29uc3QgZGV0YWlsID0gJ2RldGFpbCcgaW4gZXZlbnQgJiYgZXZlbnQuZGV0YWlsICE9PSBudWxsID8gZXZlbnQuZGV0YWlsIDogdW5kZWZpbmVkO1xuICAgICAgICBoYW5kbGVyKGRldGFpbCk7XG4gICAgfTtcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihgb3Blbm1yczoke2V2ZW50fWAsIGludGVybmFsSGFuZGxlcik7XG4gICAgcmV0dXJuICgpPT57XG4gICAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKGBvcGVubXJzOiR7ZXZlbnR9YCwgaW50ZXJuYWxIYW5kbGVyKTtcbiAgICB9O1xufVxuIl0sIm5hbWVzIjpbImZpcmVPcGVubXJzRXZlbnQiLCJldmVudCIsInBheWxvYWQiLCJldnQiLCJDdXN0b21FdmVudCIsImRldGFpbCIsInVuZGVmaW5lZCIsImNhbmNlbGFibGUiLCJidWJibGVzIiwid2luZG93IiwiZGlzcGF0Y2hFdmVudCIsInN1YnNjcmliZU9wZW5tcnNFdmVudCIsImhhbmRsZXIiLCJpbnRlcm5hbEhhbmRsZXIiLCJhZGRFdmVudExpc3RlbmVyIiwicmVtb3ZlRXZlbnRMaXN0ZW5lciJdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///../../framework/esm-emr-api/dist/events/index.js\n");
248
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ fireOpenmrsEvent: () => (/* binding */ fireOpenmrsEvent),\n/* harmony export */ subscribeOpenmrsEvent: () => (/* binding */ subscribeOpenmrsEvent)\n/* harmony export */ });\n/**\n * Fires an OpenMRS custom event\n *\n * @param event The custom event to fire\n * @param payload The payload associated with this type of event\n * @returns true if the event was not cancelled and false, i.e., the result of `dispatchEvent()`\n */ function fireOpenmrsEvent(event, payload) {\n const evt = new CustomEvent(`openmrs:${event}`, {\n detail: payload ?? undefined,\n cancelable: true,\n bubbles: true\n });\n return window.dispatchEvent(evt);\n}\nfunction subscribeOpenmrsEvent(event, handler) {\n const internalHandler = (event)=>{\n const detail = 'detail' in event && event.detail !== null ? event.detail : undefined;\n handler(detail);\n };\n window.addEventListener(`openmrs:${event}`, internalHandler);\n return ()=>{\n window.removeEventListener(`openmrs:${event}`, internalHandler);\n };\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi4vLi4vZnJhbWV3b3JrL2VzbS1lbXItYXBpL2Rpc3QvZXZlbnRzL2luZGV4LmpzIiwibWFwcGluZ3MiOiI7Ozs7O0FBQUE7Ozs7OztDQU1DLEdBQVUsU0FBU0EsaUJBQWlCQyxLQUFLLEVBQUVDLE9BQU87SUFDL0MsTUFBTUMsTUFBTSxJQUFJQyxZQUFZLENBQUMsUUFBUSxFQUFFSCxPQUFPLEVBQUU7UUFDNUNJLFFBQVFILFdBQVdJO1FBQ25CQyxZQUFZO1FBQ1pDLFNBQVM7SUFDYjtJQUNBLE9BQU9DLE9BQU9DLGFBQWEsQ0FBQ1A7QUFDaEM7QUFDTyxTQUFTUSxzQkFBc0JWLEtBQUssRUFBRVcsT0FBTztJQUNoRCxNQUFNQyxrQkFBa0IsQ0FBQ1o7UUFDckIsTUFBTUksU0FBUyxZQUFZSixTQUFTQSxNQUFNSSxNQUFNLEtBQUssT0FBT0osTUFBTUksTUFBTSxHQUFHQztRQUMzRU0sUUFBUVA7SUFDWjtJQUNBSSxPQUFPSyxnQkFBZ0IsQ0FBQyxDQUFDLFFBQVEsRUFBRWIsT0FBTyxFQUFFWTtJQUM1QyxPQUFPO1FBQ0hKLE9BQU9NLG1CQUFtQixDQUFDLENBQUMsUUFBUSxFQUFFZCxPQUFPLEVBQUVZO0lBQ25EO0FBQ0oiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9Ab3Blbm1ycy9lc20tYXBwLXNoZWxsLy4uLy4uL2ZyYW1ld29yay9lc20tZW1yLWFwaS9kaXN0L2V2ZW50cy9pbmRleC5qcz8yNzljIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogRmlyZXMgYW4gT3Blbk1SUyBjdXN0b20gZXZlbnRcbiAqXG4gKiBAcGFyYW0gZXZlbnQgVGhlIGN1c3RvbSBldmVudCB0byBmaXJlXG4gKiBAcGFyYW0gcGF5bG9hZCBUaGUgcGF5bG9hZCBhc3NvY2lhdGVkIHdpdGggdGhpcyB0eXBlIG9mIGV2ZW50XG4gKiBAcmV0dXJucyB0cnVlIGlmIHRoZSBldmVudCB3YXMgbm90IGNhbmNlbGxlZCBhbmQgZmFsc2UsIGkuZS4sIHRoZSByZXN1bHQgb2YgYGRpc3BhdGNoRXZlbnQoKWBcbiAqLyBleHBvcnQgZnVuY3Rpb24gZmlyZU9wZW5tcnNFdmVudChldmVudCwgcGF5bG9hZCkge1xuICAgIGNvbnN0IGV2dCA9IG5ldyBDdXN0b21FdmVudChgb3Blbm1yczoke2V2ZW50fWAsIHtcbiAgICAgICAgZGV0YWlsOiBwYXlsb2FkID8/IHVuZGVmaW5lZCxcbiAgICAgICAgY2FuY2VsYWJsZTogdHJ1ZSxcbiAgICAgICAgYnViYmxlczogdHJ1ZVxuICAgIH0pO1xuICAgIHJldHVybiB3aW5kb3cuZGlzcGF0Y2hFdmVudChldnQpO1xufVxuZXhwb3J0IGZ1bmN0aW9uIHN1YnNjcmliZU9wZW5tcnNFdmVudChldmVudCwgaGFuZGxlcikge1xuICAgIGNvbnN0IGludGVybmFsSGFuZGxlciA9IChldmVudCk9PntcbiAgICAgICAgY29uc3QgZGV0YWlsID0gJ2RldGFpbCcgaW4gZXZlbnQgJiYgZXZlbnQuZGV0YWlsICE9PSBudWxsID8gZXZlbnQuZGV0YWlsIDogdW5kZWZpbmVkO1xuICAgICAgICBoYW5kbGVyKGRldGFpbCk7XG4gICAgfTtcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihgb3Blbm1yczoke2V2ZW50fWAsIGludGVybmFsSGFuZGxlcik7XG4gICAgcmV0dXJuICgpPT57XG4gICAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKGBvcGVubXJzOiR7ZXZlbnR9YCwgaW50ZXJuYWxIYW5kbGVyKTtcbiAgICB9O1xufVxuIl0sIm5hbWVzIjpbImZpcmVPcGVubXJzRXZlbnQiLCJldmVudCIsInBheWxvYWQiLCJldnQiLCJDdXN0b21FdmVudCIsImRldGFpbCIsInVuZGVmaW5lZCIsImNhbmNlbGFibGUiLCJidWJibGVzIiwid2luZG93IiwiZGlzcGF0Y2hFdmVudCIsInN1YnNjcmliZU9wZW5tcnNFdmVudCIsImhhbmRsZXIiLCJpbnRlcm5hbEhhbmRsZXIiLCJhZGRFdmVudExpc3RlbmVyIiwicmVtb3ZlRXZlbnRMaXN0ZW5lciJdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///../../framework/esm-emr-api/dist/events/index.js\n");
249
249
 
250
250
  /***/ }),
251
251
 
@@ -445,7 +445,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
445
445
  \*********************************************************/
446
446
  /***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
447
447
 
448
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ attach: () => (/* binding */ attach),\n/* harmony export */ detach: () => (/* binding */ detach),\n/* harmony export */ detachAll: () => (/* binding */ detachAll),\n/* harmony export */ getAssignedExtensions: () => (/* binding */ getAssignedExtensions),\n/* harmony export */ getExtensionNameFromId: () => (/* binding */ getExtensionNameFromId),\n/* harmony export */ getExtensionRegistration: () => (/* binding */ getExtensionRegistration),\n/* harmony export */ getExtensionRegistrationFrom: () => (/* binding */ getExtensionRegistrationFrom),\n/* harmony export */ registerExtension: () => (/* binding */ registerExtension),\n/* harmony export */ registerExtensionSlot: () => (/* binding */ registerExtensionSlot),\n/* harmony export */ reset: () => (/* binding */ reset),\n/* harmony export */ updateExtensionSlotState: () => (/* binding */ updateExtensionSlotState)\n/* harmony export */ });\n/* harmony import */ var _openmrs_esm_api__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @openmrs/esm-api */ \"../../framework/esm-api/dist/index.js\");\n/* harmony import */ var _openmrs_esm_config__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @openmrs/esm-config */ \"../../framework/esm-config/dist/index.js\");\n/* harmony import */ var _openmrs_esm_expression_evaluator__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! @openmrs/esm-expression-evaluator */ \"../../framework/esm-expression-evaluator/dist/evaluator.js\");\n/* harmony import */ var _openmrs_esm_feature_flags__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @openmrs/esm-feature-flags */ \"../../framework/esm-feature-flags/dist/index.js\");\n/* harmony import */ var _openmrs_esm_globals__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @openmrs/esm-globals */ \"../../framework/esm-globals/dist/index.js\");\n/* harmony import */ var _openmrs_esm_utils__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @openmrs/esm-utils */ \"../../framework/esm-utils/dist/is-online.js\");\n/* harmony import */ var lodash_es__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! lodash-es */ \"../../../node_modules/lodash-es/isEqual.js\");\n/* harmony import */ var lodash_es__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! lodash-es */ \"../../../node_modules/lodash-es/merge.js\");\n/* harmony import */ var _helpers_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./helpers.js */ \"../../framework/esm-extensions/dist/helpers.js\");\n/* harmony import */ var _store_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./store.js */ \"../../framework/esm-extensions/dist/store.js\");\n/** @module @category Extension */ /*\n * We have the following extension modes:\n *\n * - attached (set via code in form of: attach, detach, ...)\n * - configured (set via configuration in form of: added, removed, ...)\n * - assigned (computed from attached and configured)\n * - connected (computed from assigned using connectivity and online / offline)\n */ \n\n\n\n\n\n\n\n\nconst extensionInternalStore = (0,_store_js__WEBPACK_IMPORTED_MODULE_5__.getExtensionInternalStore)();\nconst extensionStore = (0,_store_js__WEBPACK_IMPORTED_MODULE_5__.getExtensionStore)();\nconst slotsConfigStore = (0,_openmrs_esm_config__WEBPACK_IMPORTED_MODULE_1__.getExtensionSlotsConfigStore)();\nconst extensionsConfigStore = (0,_openmrs_esm_config__WEBPACK_IMPORTED_MODULE_1__.getExtensionsConfigStore)();\n// Keep the output store updated\nfunction updateExtensionOutputStore(internalState, extensionSlotConfigs, extensionsConfigStore, featureFlagStore, sessionStore) {\n const slots = {};\n const isOnline = (0,_openmrs_esm_utils__WEBPACK_IMPORTED_MODULE_6__.isOnline)();\n const enabledFeatureFlags = Object.entries(featureFlagStore.flags).filter(([, { enabled }])=>enabled).map(([name])=>name);\n for (let [slotName, slot] of Object.entries(internalState.slots)){\n const { config } = (0,_openmrs_esm_config__WEBPACK_IMPORTED_MODULE_1__.getExtensionSlotConfigFromStore)(extensionSlotConfigs, slot.name);\n const assignedExtensions = getAssignedExtensionsFromSlotData(slotName, internalState, config, extensionsConfigStore, enabledFeatureFlags, isOnline, sessionStore.session);\n slots[slotName] = {\n moduleName: slot.moduleName,\n assignedExtensions\n };\n }\n if (!(0,lodash_es__WEBPACK_IMPORTED_MODULE_7__[\"default\"])(extensionStore.getState().slots, slots)) {\n extensionStore.setState({\n slots\n });\n }\n}\nextensionInternalStore.subscribe((internalStore)=>{\n updateExtensionOutputStore(internalStore, slotsConfigStore.getState(), extensionsConfigStore.getState(), _openmrs_esm_feature_flags__WEBPACK_IMPORTED_MODULE_2__.featureFlagsStore.getState(), _openmrs_esm_api__WEBPACK_IMPORTED_MODULE_0__.sessionStore.getState());\n});\nslotsConfigStore.subscribe((slotConfigs)=>{\n updateExtensionOutputStore(extensionInternalStore.getState(), slotConfigs, extensionsConfigStore.getState(), _openmrs_esm_feature_flags__WEBPACK_IMPORTED_MODULE_2__.featureFlagsStore.getState(), _openmrs_esm_api__WEBPACK_IMPORTED_MODULE_0__.sessionStore.getState());\n});\nextensionsConfigStore.subscribe((extensionConfigs)=>{\n updateExtensionOutputStore(extensionInternalStore.getState(), slotsConfigStore.getState(), extensionConfigs, _openmrs_esm_feature_flags__WEBPACK_IMPORTED_MODULE_2__.featureFlagsStore.getState(), _openmrs_esm_api__WEBPACK_IMPORTED_MODULE_0__.sessionStore.getState());\n});\n_openmrs_esm_feature_flags__WEBPACK_IMPORTED_MODULE_2__.featureFlagsStore.subscribe((featureFlagStore)=>{\n updateExtensionOutputStore(extensionInternalStore.getState(), slotsConfigStore.getState(), extensionsConfigStore.getState(), featureFlagStore, _openmrs_esm_api__WEBPACK_IMPORTED_MODULE_0__.sessionStore.getState());\n});\n_openmrs_esm_api__WEBPACK_IMPORTED_MODULE_0__.sessionStore.subscribe((session)=>{\n updateExtensionOutputStore(extensionInternalStore.getState(), slotsConfigStore.getState(), extensionsConfigStore.getState(), _openmrs_esm_feature_flags__WEBPACK_IMPORTED_MODULE_2__.featureFlagsStore.getState(), session);\n});\nfunction updateOutputStoreToCurrent() {\n updateExtensionOutputStore(extensionInternalStore.getState(), slotsConfigStore.getState(), extensionsConfigStore.getState(), _openmrs_esm_feature_flags__WEBPACK_IMPORTED_MODULE_2__.featureFlagsStore.getState(), _openmrs_esm_api__WEBPACK_IMPORTED_MODULE_0__.sessionStore.getState());\n}\nupdateOutputStoreToCurrent();\n(0,_openmrs_esm_globals__WEBPACK_IMPORTED_MODULE_3__.subscribeConnectivityChanged)(updateOutputStoreToCurrent);\nfunction createNewExtensionSlotInfo(slotName, moduleName, state) {\n return {\n moduleName,\n name: slotName,\n attachedIds: [],\n config: null,\n state\n };\n}\n/**\n * Given an extension ID, which is a string uniquely identifying\n * an instance of an extension within an extension slot, this\n * returns the extension name.\n *\n * @example\n * ```js\n * getExtensionNameFromId(\"foo#bar\")\n * --> \"foo\"\n * getExtensionNameFromId(\"baz\")\n * --> \"baz\"\n * ```\n */ function getExtensionNameFromId(extensionId) {\n const [extensionName] = extensionId.split('#');\n return extensionName;\n}\nfunction getExtensionRegistrationFrom(state, extensionId) {\n const name = getExtensionNameFromId(extensionId);\n return state.extensions[name];\n}\nfunction getExtensionRegistration(extensionId) {\n const state = extensionInternalStore.getState();\n return getExtensionRegistrationFrom(state, extensionId);\n}\n/**\n * Extensions must be registered in order to be rendered.\n * This is handled by the app shell, when extensions are provided\n * via the `setupOpenMRS` return object.\n * @internal\n */ const registerExtension = (extensionRegistration)=>extensionInternalStore.setState((state)=>{\n state.extensions[extensionRegistration.name] = {\n ...extensionRegistration,\n instances: []\n };\n return state;\n });\n/**\n * Attach an extension to an extension slot.\n *\n * This will cause the extension to be rendered into the specified\n * extension slot, unless it is removed by configuration. Using\n * `attach` is an alternative to specifying the `slot` or `slots`\n * in the extension declaration.\n *\n * It is particularly useful when creating a slot into which\n * you want to render an existing extension. This enables you\n * to do so without modifying the extension's declaration, which\n * may be impractical or inappropriate, for example if you are\n * writing a module for a specific implementation.\n *\n * @param slotName a name uniquely identifying the slot\n * @param extensionId an extension name, with an optional #-suffix\n * to distinguish it from other instances of the same extension\n * attached to the same slot.\n */ function attach(slotName, extensionId) {\n (0,_store_js__WEBPACK_IMPORTED_MODULE_5__.updateInternalExtensionStore)((state)=>{\n const existingSlot = state.slots[slotName];\n if (!existingSlot) {\n return {\n ...state,\n slots: {\n ...state.slots,\n [slotName]: {\n ...createNewExtensionSlotInfo(slotName),\n attachedIds: [\n extensionId\n ]\n }\n }\n };\n } else {\n return {\n ...state,\n slots: {\n ...state.slots,\n [slotName]: {\n ...existingSlot,\n attachedIds: [\n ...existingSlot.attachedIds,\n extensionId\n ]\n }\n }\n };\n }\n });\n}\n/**\n * @deprecated Avoid using this. Extension attachments should be considered declarative.\n */ function detach(extensionSlotName, extensionId) {\n (0,_store_js__WEBPACK_IMPORTED_MODULE_5__.updateInternalExtensionStore)((state)=>{\n const existingSlot = state.slots[extensionSlotName];\n if (existingSlot && existingSlot.attachedIds.includes(extensionId)) {\n return {\n ...state,\n slots: {\n ...state.slots,\n [extensionSlotName]: {\n ...existingSlot,\n attachedIds: existingSlot.attachedIds.filter((id)=>id !== extensionId)\n }\n }\n };\n } else {\n return state;\n }\n });\n}\n/**\n * @deprecated Avoid using this. Extension attachments should be considered declarative.\n */ function detachAll(extensionSlotName) {\n (0,_store_js__WEBPACK_IMPORTED_MODULE_5__.updateInternalExtensionStore)((state)=>{\n const existingSlot = state.slots[extensionSlotName];\n if (existingSlot) {\n return {\n ...state,\n slots: {\n ...state.slots,\n [extensionSlotName]: {\n ...existingSlot,\n attachedIds: []\n }\n }\n };\n } else {\n return state;\n }\n });\n}\n/**\n * Get an order index for the extension. This will\n * come from either its configured order, its registered order\n * parameter, or the order in which it happened to be attached.\n */ function getOrder(extensionId, configuredOrder, registeredOrderIndex, attachedOrder) {\n const configuredIndex = configuredOrder.indexOf(extensionId);\n if (configuredIndex !== -1) {\n return configuredIndex;\n } else if (registeredOrderIndex !== undefined) {\n // extensions that don't have a configured order should appear after those that do\n return 1000 + registeredOrderIndex;\n } else {\n const assignedIndex = attachedOrder.indexOf(extensionId);\n if (assignedIndex !== -1) {\n // extensions that have neither a configured nor registered order should appear\n // after all others\n return 2000 + assignedIndex;\n } else {\n return -1;\n }\n }\n}\nfunction getAssignedExtensionsFromSlotData(slotName, internalState, config, extensionConfigStoreState, enabledFeatureFlags, isOnline, session) {\n const attachedIds = internalState.slots[slotName].attachedIds;\n const assignedIds = calculateAssignedIds(config, attachedIds);\n const extensions = [];\n // Create context once for all extensions in this slot\n const slotState = internalState.slots[slotName]?.state;\n const expressionContext = slotState && typeof slotState === 'object' ? {\n session,\n ...slotState\n } : {\n session\n };\n for (let id of assignedIds){\n const { config: rawExtensionConfig } = (0,_openmrs_esm_config__WEBPACK_IMPORTED_MODULE_1__.getExtensionConfigFromStore)(extensionConfigStoreState, slotName, id);\n const rawExtensionSlotExtensionConfig = (0,_openmrs_esm_config__WEBPACK_IMPORTED_MODULE_1__.getExtensionConfigFromExtensionSlotStore)(config, slotName, id);\n const extensionConfig = (0,lodash_es__WEBPACK_IMPORTED_MODULE_8__[\"default\"])(rawExtensionConfig, rawExtensionSlotExtensionConfig);\n const name = getExtensionNameFromId(id);\n const extension = internalState.extensions[name];\n // if the extension has not been registered yet, do not include it\n if (extension) {\n const requiredPrivileges = extensionConfig?.['Display conditions']?.privileges ?? extension.privileges ?? [];\n if (requiredPrivileges && (typeof requiredPrivileges === 'string' || Array.isArray(requiredPrivileges) && requiredPrivileges.length > 0)) {\n if (!session?.user) {\n continue;\n }\n if (!(0,_openmrs_esm_api__WEBPACK_IMPORTED_MODULE_0__.userHasAccess)(requiredPrivileges, session.user)) {\n continue;\n }\n }\n const displayConditionExpression = extensionConfig?.['Display conditions']?.expression || extension.displayExpression;\n if (displayConditionExpression !== undefined && typeof displayConditionExpression === 'string' && displayConditionExpression.trim().length > 0) {\n try {\n if (!(0,_openmrs_esm_expression_evaluator__WEBPACK_IMPORTED_MODULE_9__.evaluateAsBoolean)(displayConditionExpression, expressionContext)) {\n continue;\n }\n } catch (e) {\n console.error(`Error while evaluating expression '${displayConditionExpression}' for extension ${name} in slot ${slotName}`, e);\n continue;\n }\n }\n if (extension.featureFlag && !enabledFeatureFlags.includes(extension.featureFlag)) {\n continue;\n }\n if (window.offlineEnabled && !(0,_helpers_js__WEBPACK_IMPORTED_MODULE_4__.checkStatusFor)(isOnline, extension.online, extension.offline)) {\n continue;\n }\n extensions.push({\n id,\n name,\n moduleName: extension.moduleName,\n config: extensionConfig,\n featureFlag: extension.featureFlag,\n meta: extension.meta,\n online: extensionConfig?.['Display conditions']?.online ?? extension.online ?? true,\n offline: extensionConfig?.['Display conditions']?.offline ?? extension.offline ?? false\n });\n }\n }\n return extensions;\n}\n/**\n * Gets the list of extensions assigned to a given slot\n *\n * @param slotName The slot to load the assigned extensions for\n * @returns An array of extensions assigned to the named slot\n */ function getAssignedExtensions(slotName) {\n const internalState = extensionInternalStore.getState();\n const { config: slotConfig } = (0,_openmrs_esm_config__WEBPACK_IMPORTED_MODULE_1__.getExtensionSlotConfig)(slotName);\n const extensionStoreState = extensionsConfigStore.getState();\n const featureFlagState = _openmrs_esm_feature_flags__WEBPACK_IMPORTED_MODULE_2__.featureFlagsStore.getState();\n const sessionState = _openmrs_esm_api__WEBPACK_IMPORTED_MODULE_0__.sessionStore.getState();\n const isOnline = (0,_openmrs_esm_utils__WEBPACK_IMPORTED_MODULE_6__.isOnline)();\n const enabledFeatureFlags = Object.entries(featureFlagState.flags).filter(([, { enabled }])=>enabled).map(([name])=>name);\n return getAssignedExtensionsFromSlotData(slotName, internalState, slotConfig, extensionStoreState, enabledFeatureFlags, isOnline, sessionState.session);\n}\nfunction calculateAssignedIds(config, attachedIds) {\n const addedIds = config.add || [];\n const removedIds = config.remove || [];\n const idOrder = config.order || [];\n const { extensions } = extensionInternalStore.getState();\n return [\n ...attachedIds,\n ...addedIds\n ].filter((id)=>!removedIds.includes(id)).sort((idA, idB)=>{\n const ai = getOrder(idA, idOrder, extensions[getExtensionNameFromId(idA)]?.order, attachedIds);\n const bi = getOrder(idB, idOrder, extensions[getExtensionNameFromId(idB)]?.order, attachedIds);\n if (bi === -1) {\n return -1;\n } else if (ai === -1) {\n return 1;\n } else {\n return ai - bi;\n }\n });\n}\n/**\n * Used by by extension slots at mount time.\n *\n * @param moduleName The name of the module that contains the extension slot\n * @param slotName The extension slot name that is actually used\n * @param state Optional custom state for the slot, which will be stored in the extension store.\n * @internal\n */ const registerExtensionSlot = (moduleName, slotName, state)=>extensionInternalStore.setState((currentState)=>{\n const existingModuleName = currentState.slots[slotName]?.moduleName;\n if (existingModuleName && existingModuleName != moduleName) {\n console.warn(`An extension slot with the name '${slotName}' already exists. Refusing to register the same slot name twice (in \"registerExtensionSlot\"). The existing one is from module ${existingModuleName}.`);\n return currentState;\n }\n if (existingModuleName && existingModuleName == moduleName) {\n // Re-rendering an existing slot\n return currentState;\n }\n if (currentState.slots[slotName]) {\n return {\n ...currentState,\n slots: {\n ...currentState.slots,\n [slotName]: {\n ...currentState.slots[slotName],\n moduleName,\n state\n }\n }\n };\n }\n const slot = createNewExtensionSlotInfo(slotName, moduleName, state);\n return {\n ...currentState,\n slots: {\n ...currentState.slots,\n [slotName]: {\n ...slot\n }\n }\n };\n });\n/**\n * Used by extension slots to update the copy of the state for the extension slot\n *\n * @param slotName The name of the slot with state to update\n * @param state A copy of the new state\n * @param partial Whether this should be applied as a partial\n */ function updateExtensionSlotState(slotName, state, partial = false) {\n extensionInternalStore.setState((currentState)=>{\n const newState = partial ? (0,lodash_es__WEBPACK_IMPORTED_MODULE_8__[\"default\"])(currentState.slots[slotName].state, state) : state;\n return {\n ...currentState,\n slots: {\n ...currentState.slots,\n [slotName]: {\n ...currentState.slots[slotName],\n state: newState\n }\n }\n };\n });\n}\n/**\n * @internal\n * Just for testing.\n */ const reset = ()=>extensionStore.setState(()=>{\n return {\n slots: {},\n extensions: {}\n };\n });\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi4vLi4vZnJhbWV3b3JrL2VzbS1leHRlbnNpb25zL2Rpc3QvZXh0ZW5zaW9ucy5qcyIsIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSxnQ0FBZ0MsR0FBRzs7Ozs7OztDQU9sQyxHQUFrRTtBQUMwSjtBQUN2SjtBQUNQO0FBQ0s7QUFDUjtBQUNqQjtBQUNHO0FBQzBEO0FBQ3hHLE1BQU1tQix5QkFBeUJILG9FQUF5QkE7QUFDeEQsTUFBTUksaUJBQWlCSCw0REFBaUJBO0FBQ3hDLE1BQU1JLG1CQUFtQmYsaUZBQTRCQTtBQUNyRCxNQUFNZ0Isd0JBQXdCZiw2RUFBd0JBO0FBQ3RELGdDQUFnQztBQUNoQyxTQUFTZ0IsMkJBQTJCQyxhQUFhLEVBQUVDLG9CQUFvQixFQUFFSCxxQkFBcUIsRUFBRUksZ0JBQWdCLEVBQUUxQixZQUFZO0lBQzFILE1BQU0yQixRQUFRLENBQUM7SUFDZixNQUFNaEIsV0FBV0MsNERBQVVBO0lBQzNCLE1BQU1nQixzQkFBc0JDLE9BQU9DLE9BQU8sQ0FBQ0osaUJBQWlCSyxLQUFLLEVBQUVDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsRUFBRUMsT0FBTyxFQUFFLENBQUMsR0FBR0EsU0FBU0MsR0FBRyxDQUFDLENBQUMsQ0FBQ0MsS0FBSyxHQUFHQTtJQUNwSCxLQUFLLElBQUksQ0FBQ0MsVUFBVUMsS0FBSyxJQUFJUixPQUFPQyxPQUFPLENBQUNOLGNBQWNHLEtBQUssRUFBRTtRQUM3RCxNQUFNLEVBQUVXLE1BQU0sRUFBRSxHQUFHakMsb0ZBQStCQSxDQUFDb0Isc0JBQXNCWSxLQUFLRixJQUFJO1FBQ2xGLE1BQU1JLHFCQUFxQkMsa0NBQWtDSixVQUFVWixlQUFlYyxRQUFRaEIsdUJBQXVCTSxxQkFBcUJqQixVQUFVWCxhQUFheUMsT0FBTztRQUN4S2QsS0FBSyxDQUFDUyxTQUFTLEdBQUc7WUFDZE0sWUFBWUwsS0FBS0ssVUFBVTtZQUMzQkg7UUFDSjtJQUNKO0lBQ0EsSUFBSSxDQUFDMUIscURBQU9BLENBQUNP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O0lBQ0osR0FBRyIsInNvdXJjZXMiOlsid2VicGFjazovL0BvcGVubXJzL2VzbS1hcHAtc2hlbGwvLi4vLi4vZnJhbWV3b3JrL2VzbS1leHRlbnNpb25zL2Rpc3QvZXh0ZW5zaW9ucy5qcz9jMGU3Il0sInNvdXJjZXNDb250ZW50IjpbIi8qKiBAbW9kdWxlIEBjYXRlZ29yeSBFeHRlbnNpb24gKi8gLypcbiAqIFdlIGhhdmUgdGhlIGZvbGxvd2luZyBleHRlbnNpb24gbW9kZXM6XG4gKlxuICogLSBhdHRhY2hlZCAoc2V0IHZpYSBjb2RlIGluIGZvcm0gb2Y6IGF0dGFjaCwgZGV0YWNoLCAuLi4pXG4gKiAtIGNvbmZpZ3VyZWQgKHNldCB2aWEgY29uZmlndXJhdGlvbiBpbiBmb3JtIG9mOiBhZGRlZCwgcmVtb3ZlZCwgLi4uKVxuICogLSBhc3NpZ25lZCAoY29tcHV0ZWQgZnJvbSBhdHRhY2hlZCBhbmQgY29uZmlndXJlZClcbiAqIC0gY29ubmVjdGVkIChjb21wdXRlZCBmcm9tIGFzc2lnbmVkIHVzaW5nIGNvbm5lY3Rpdml0eSBhbmQgb25saW5lIC8gb2ZmbGluZSlcbiAqLyBpbXBvcnQgeyBzZXNzaW9uU3RvcmUsIHVzZXJIYXNBY2Nlc3MgfSBmcm9tIFwiQG9wZW5tcnMvZXNtLWFwaVwiO1xuaW1wb3J0IHsgZ2V0RXh0ZW5zaW9uQ29uZmlnRnJvbUV4dGVuc2lvblNsb3RTdG9yZSwgZ2V0RXh0ZW5zaW9uQ29uZmlnRnJvbVN0b3JlLCBnZXRFeHRlbnNpb25TbG90Q29uZmlnLCBnZXRFeHRlbnNpb25TbG90Q29uZmlnRnJvbVN0b3JlLCBnZXRFeHRlbnNpb25TbG90c0NvbmZpZ1N0b3JlLCBnZXRFeHRlbnNpb25zQ29uZmlnU3RvcmUgfSBmcm9tIFwiQG9wZW5tcnMvZXNtLWNvbmZpZ1wiO1xuaW1wb3J0IHsgZXZhbHVhdGVBc0Jvb2xlYW4gfSBmcm9tIFwiQG9wZW5tcnMvZXNtLWV4cHJlc3Npb24tZXZhbHVhdG9yXCI7XG5pbXBvcnQgeyBmZWF0dXJlRmxhZ3NTdG9yZSB9IGZyb20gXCJAb3Blbm1ycy9lc20tZmVhdHVyZS1mbGFnc1wiO1xuaW1wb3J0IHsgc3Vic2NyaWJlQ29ubmVjdGl2aXR5Q2hhbmdlZCB9IGZyb20gXCJAb3Blbm1ycy9lc20tZ2xvYmFsc1wiO1xuaW1wb3J0IHsgaXNPbmxpbmUgYXMgaXNPbmxpbmVGbiB9IGZyb20gXCJAb3Blbm1ycy9lc20tdXRpbHNcIjtcbmltcG9ydCB7IGlzRXF1YWwsIG1lcmdlIH0gZnJvbSBcImxvZGFzaC1lc1wiO1xuaW1wb3J0IHsgY2hlY2tTdGF0dXNGb3IgfSBmcm9tIFwiLi9oZWxwZXJzLmpzXCI7XG5pbXBvcnQgeyBnZXRFeHRlbnNpb25JbnRlcm5hbFN0b3JlLCBnZXRFeHRlbnNpb25TdG9yZSwgdXBkYXRlSW50ZXJuYWxFeHRlbnNpb25TdG9yZSB9IGZyb20gXCIuL3N0b3JlLmpzXCI7XG5jb25zdCBleHRlbnNpb25JbnRlcm5hbFN0b3JlID0gZ2V0RXh0ZW5zaW9uSW50ZXJuYWxTdG9yZSgpO1xuY29uc3QgZXh0ZW5zaW9uU3RvcmUgPSBnZXRFeHRlbnNpb25TdG9yZSgpO1xuY29uc3Qgc2xvdHNDb25maWdTdG9yZSA9IGdldEV4dGVuc2lvblNsb3RzQ29uZmlnU3RvcmUoKTtcbmNvbnN0IGV4dGVuc2lvbnNDb25maWdTdG9yZSA9IGdldEV4dGVuc2lvbnNDb25maWdTdG9yZSgpO1xuLy8gS2VlcCB0aGUgb3V0cHV0IHN0b3JlIHVwZGF0ZWRcbmZ1bmN0aW9uIHVwZGF0ZUV4dGVuc2lvbk91dHB1dFN0b3JlKGludGVybmFsU3RhdGUsIGV4dGVuc2lvblNsb3RDb25maWdzLCBleHRlbnNpb25zQ29uZmlnU3RvcmUsIGZlYXR1cmVGbGFnU3RvcmUsIHNlc3Npb25TdG9yZSkge1xuICAgIGNvbnN0IHNsb3RzID0ge307XG4gICAgY29uc3QgaXNPbmxpbmUgPSBpc09ubGluZUZuKCk7XG4gICAgY29uc3QgZW5hYmxlZEZlYXR1cmVGbGFncyA9IE9iamVjdC5lbnRyaWVzKGZlYXR1cmVGbGFnU3RvcmUuZmxhZ3MpLmZpbHRlcigoWywgeyBlbmFibGVkIH1dKT0+ZW5hYmxlZCkubWFwKChbbmFtZV0pPT5uYW1lKTtcbiAgICBmb3IgKGxldCBbc2xvdE5hbWUsIHNsb3RdIG9mIE9iamVjdC5lbnRyaWVzKGludGVybmFsU3RhdGUuc2xvdHMpKXtcbiAgICAgICAgY29uc3QgeyBjb25maWcgfSA9IGdldEV4dGVuc2lvblNsb3RDb25maWdGcm9tU3RvcmUoZXh0ZW5zaW9uU2xvdENvbmZpZ3MsIHNsb3QubmFtZSk7XG4gICAgICAgIGNvbnN0IGFzc2lnbmVkRXh0ZW5zaW9ucyA9IGdldEFzc2lnbmVkRXh0ZW5zaW9uc0Zyb21TbG90RGF0YShzbG90TmFtZSwgaW50ZXJuYWxTdGF0ZSwgY29uZmlnLCBleHRlbnNpb25zQ29uZmlnU3RvcmUsIGVuYWJsZWRGZWF0dXJlRmxhZ3MsIGlzT25saW5lLCBzZXNzaW9uU3RvcmUuc2Vzc2lvbik7XG4gICAgICAgIHNsb3RzW3Nsb3ROYW1lXSA9IHtcbiAgICAgICAgICAgIG1vZHVsZU5hbWU6IHNsb3QubW9kdWxlTmFtZSxcbiAgICAgICAgICAgIGFzc2lnbmVkRXh0ZW5zaW9uc1xuICAgICAgICB9O1xuICAgIH1cbiAgICBpZiAoIWlzRXF1YWwoZXh0ZW5zaW9uU3RvcmUuZ2V0U3RhdGUoKS5zbG90cywgc2xvdHMpKSB7XG4gICAgICAgIGV4dGVuc2lvblN0b3JlLnNldFN0YXRlKHtcbiAgICAgICAgICAgIHNsb3RzXG4gICAgICAgIH0pO1xuICAgIH1cbn1cbmV4dGVuc2lvbkludGVybmFsU3RvcmUuc3Vic2NyaWJlKChpbnRlcm5hbFN0b3JlKT0+e1xuICAgIHVwZGF0ZUV4dGVuc2lvbk91dHB1dFN0b3JlKGludGVybmFsU3RvcmUsIHNsb3RzQ29uZmlnU3RvcmUuZ2V0U3RhdGUoKSwgZXh0ZW5zaW9uc0NvbmZpZ1N0b3JlLmdldFN0YXRlKCksIGZlYXR1cmVGbGFnc1N0b3JlLmdldFN0YXRlKCksIHNlc3Npb25TdG9yZS5nZXRTdGF0ZSgpKTtcbn0pO1xuc2xvdHNDb25maWdTdG9yZS5zdWJzY3JpYmUoKHNsb3RDb25maWdzKT0+e1xuICAgIHVwZGF0ZUV4dGVuc2lvbk91dHB1dFN0b3JlKGV4dGVuc2lvbkludGVybmFsU3RvcmUuZ2V0U3RhdGUoKSwgc2xvdENvbmZpZ3MsIGV4dGVuc2lvbnNDb25maWdTdG9yZS5nZXRTdGF0ZSgpLCBmZWF0dXJlRmxhZ3NTdG9yZS5nZXRTdGF0ZSgpLCBzZXNzaW9uU3RvcmUuZ2V0U3RhdGUoKSk7XG59KTtcbmV4dGVuc2lvbnNDb25maWdTdG9yZS5zdWJzY3JpYmUoKGV4dGVuc2lvbkNvbmZpZ3MpPT57XG4gICAgdXBkYXRlRXh0ZW5zaW9uT3V0cHV0U3RvcmUoZXh0ZW5zaW9uSW50ZXJuYWxTdG9yZS5nZXRTdGF0ZSgpLCBzbG90c0NvbmZpZ1N0b3JlLmdldFN0YXRlKCksIGV4dGVuc2lvbkNvbmZpZ3MsIGZlYXR1cmVGbGFnc1N0b3JlLmdldFN0YXRlKCksIHNlc3Npb25TdG9yZS5nZXRTdGF0ZSgpKTtcbn0pO1xuZmVhdHVyZUZsYWdzU3RvcmUuc3Vic2NyaWJlKChmZWF0dXJlRmxhZ1N0b3JlKT0+e1xuICAgIHVwZGF0ZUV4dGVuc2lvbk91dHB1dFN0b3JlKGV4dGVuc2lvbkludGVybmFsU3RvcmUuZ2V0U3RhdGUoKSwgc2xvdHNDb25maWdTdG9yZS5nZXRTdGF0ZSgpLCBleHRlbnNpb25zQ29uZmlnU3RvcmUuZ2V0U3RhdGUoKSwgZmVhdHVyZUZsYWdTdG9yZSwgc2Vzc2lvblN0b3JlLmdldFN0YXRlKCkpO1xufSk7XG5zZXNzaW9uU3RvcmUuc3Vic2NyaWJlKChzZXNzaW9uKT0+e1xuICAgIHVwZGF0ZUV4dGVuc2lvbk91dHB1dFN0b3JlKGV4dGVuc2lvbkludGVybmFsU3RvcmUuZ2V0U3RhdGUoKSwgc2xvdHNDb25maWdTdG9yZS5nZXRTdGF0ZSgpLCBleHRlbnNpb25zQ29uZmlnU3RvcmUuZ2V0U3RhdGUoKSwgZmVhdHVyZUZsYWdzU3RvcmUuZ2V0U3RhdGUoKSwgc2Vzc2lvbik7XG59KTtcbmZ1bmN0aW9uIHVwZGF0ZU91dHB1dFN0b3JlVG9DdXJyZW50KCkge1xuICAgIHVwZGF0ZUV4dGVuc2lvbk91dHB1dFN0b3JlKGV4dGVuc2lvbkludGVybmFsU3RvcmUuZ2V0U3RhdGUoKSwgc2xvdHNDb25maWdTdG9yZS5nZXRTdGF0ZSgpLCBleHRlbnNpb25zQ29uZmlnU3RvcmUuZ2V0U3RhdGUoKSwgZmVhdHVyZUZsYWdzU3RvcmUuZ2V0U3RhdGUoKSwgc2Vzc2lvblN0b3JlLmdldFN0YXRlKCkpO1xufVxudXBkYXRlT3V0cHV0U3RvcmVUb0N1cnJlbnQoKTtcbnN1YnNjcmliZUNvbm5lY3Rpdml0eUNoYW5nZWQodXBkYXRlT3V0cHV0U3RvcmVUb0N1cnJlbnQpO1xuZnVuY3Rpb24gY3JlYXRlTmV3RXh0ZW5zaW9uU2xvdEluZm8oc2xvdE5hbWUsIG1vZHVsZU5hbWUsIHN0YXRlKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgbW9kdWxlTmFtZSxcbiAgICAgICAgbmFtZTogc2xvdE5hbWUsXG4gICAgICAgIGF0dGFjaGVkSWRzOiBbXSxcbiAgICAgICAgY29uZmlnOiBudWxsLFxuICAgICAgICBzdGF0ZVxuICAgIH07XG59XG4vKipcbiAqIEdpdmVuIGFuIGV4dGVuc2lvbiBJRCwgd2hpY2ggaXMgYSBzdHJpbmcgdW5pcXVlbHkgaWRlbnRpZnlpbmdcbiAqIGFuIGluc3RhbmNlIG9mIGFuIGV4dGVuc2lvbiB3aXRoaW4gYW4gZXh0ZW5zaW9uIHNsb3QsIHRoaXNcbiAqIHJldHVybnMgdGhlIGV4dGVuc2lvbiBuYW1lLlxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGBqc1xuICogZ2V0RXh0ZW5zaW9uTmFtZUZyb21JZChcImZvbyNiYXJcIilcbiAqICAtLT4gXCJmb29cIlxuICogZ2V0RXh0ZW5zaW9uTmFtZUZyb21JZChcImJhelwiKVxuICogIC0tPiBcImJhelwiXG4gKiBgYGBcbiAqLyBleHBvcnQgZnVuY3Rpb24gZ2V0RXh0ZW5zaW9uTmFtZUZyb21JZChleHRlbnNpb25JZCkge1xuICAgIGNvbnN0IFtleHRlbnNpb25OYW1lXSA9IGV4dGVuc2lvbklkLnNwbGl0KCcjJyk7XG4gICAgcmV0dXJuIGV4dGVuc2lvbk5hbWU7XG59XG5leHBvcnQgZnVuY3Rpb24gZ2V0RXh0ZW5zaW9uUmVnaXN0cmF0aW9uRnJvbShzdGF0ZSwgZXh0ZW5zaW9uSWQpIHtcbiAgICBjb25zdCBuYW1lID0gZ2V0RXh0ZW5zaW9uTmFtZUZyb21JZChleHRlbnNpb25JZCk7XG4gICAgcmV0dXJuIHN0YXRlLmV4dGVuc2lvbnNbbmFtZV07XG59XG5leHBvcnQgZnVuY3Rpb24gZ2V0RXh0ZW5zaW9uUmVnaXN0cmF0aW9uKGV4dGVuc2lvbklkKSB7XG4gICAgY29uc3Qgc3RhdGUgPSBleHRlbnNpb25JbnRlcm5hbFN0b3JlLmdldFN0YXRlKCk7XG4gICAgcmV0dXJuIGdldEV4dGVuc2lvblJlZ2lzdHJhdGlvbkZyb20oc3RhdGUsIGV4dGVuc2lvbklkKTtcbn1cbi8qKlxuICogRXh0ZW5zaW9ucyBtdXN0IGJlIHJlZ2lzdGVyZWQgaW4gb3JkZXIgdG8gYmUgcmVuZGVyZWQuXG4gKiBUaGlzIGlzIGhhbmRsZWQgYnkgdGhlIGFwcCBzaGVsbCwgd2hlbiBleHRlbnNpb25zIGFyZSBwcm92aWRlZFxuICogdmlhIHRoZSBgc2V0dXBPcGVuTVJTYCByZXR1cm4gb2JqZWN0LlxuICogQGludGVybmFsXG4gKi8gZXhwb3J0IGNvbnN0IHJlZ2lzdGVyRXh0ZW5zaW9uID0gKGV4dGVuc2lvblJlZ2lzdHJhdGlvbik9PmV4dGVuc2lvbkludGVybmFsU3RvcmUuc2V0U3RhdGUoKHN0YXRlKT0+e1xuICAgICAgICBzdGF0ZS5leHRlbnNpb25zW2V4dGVuc2lvblJlZ2lzdHJhdGlvbi5uYW1lXSA9IHtcbiAgICAgICAgICAgIC4uLmV4dGVuc2lvblJlZ2lzdHJhdGlvbixcbiAgICAgICAgICAgIGluc3RhbmNlczogW11cbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIHN0YXRlO1xuICAgIH0pO1xuLyoqXG4gKiBBdHRhY2ggYW4gZXh0ZW5zaW9uIHRvIGFuIGV4dGVuc2lvbiBzbG90LlxuICpcbiAqIFRoaXMgd2lsbCBjYXVzZSB0aGUgZXh0ZW5zaW9uIHRvIGJlIHJlbmRlcmVkIGludG8gdGhlIHNwZWNpZmllZFxuICogZXh0ZW5zaW9uIHNsb3QsIHVubGVzcyBpdCBpcyByZW1vdmVkIGJ5IGNvbmZpZ3VyYXRpb24uIFVzaW5nXG4gKiBgYXR0YWNoYCBpcyBhbiBhbHRlcm5hdGl2ZSB0byBzcGVjaWZ5aW5nIHRoZSBgc2xvdGAgb3IgYHNsb3RzYFxuICogaW4gdGhlIGV4dGVuc2lvbiBkZWNsYXJhdGlvbi5cbiAqXG4gKiBJdCBpcyBwYXJ0aWN1bGFybHkgdXNlZnVsIHdoZW4gY3JlYXRpbmcgYSBzbG90IGludG8gd2hpY2hcbiAqIHlvdSB3YW50IHRvIHJlbmRlciBhbiBleGlzdGluZyBleHRlbnNpb24uIFRoaXMgZW5hYmxlcyB5b3VcbiAqIHRvIGRvIHNvIHdpdGhvdXQgbW9kaWZ5aW5nIHRoZSBleHRlbnNpb24ncyBkZWNsYXJhdGlvbiwgd2hpY2hcbiAqIG1heSBiZSBpbXByYWN0aWNhbCBvciBpbmFwcHJvcHJpYXRlLCBmb3IgZXhhbXBsZSBpZiB5b3UgYXJlXG4gKiB3cml0aW5nIGEgbW9kdWxlIGZvciBhIHNwZWNpZmljIGltcGxlbWVudGF0aW9uLlxuICpcbiAqIEBwYXJhbSBzbG90TmFtZSBhIG5hbWUgdW5pcXVlbHkgaWRlbnRpZnlpbmcgdGhlIHNsb3RcbiAqIEBwYXJhbSBleHRlbnNpb25JZCBhbiBleHRlbnNpb24gbmFtZSwgd2l0aCBhbiBvcHRpb25hbCAjLXN1ZmZpeFxuICogICAgdG8gZGlzdGluZ3Vpc2ggaXQgZnJvbSBvdGhlciBpbnN0YW5jZXMgb2YgdGhlIHNhbWUgZXh0ZW5zaW9uXG4gKiAgICBhdHRhY2hlZCB0byB0aGUgc2FtZSBzbG90LlxuICovIGV4cG9ydCBmdW5jdGlvbiBhdHRhY2goc2xvdE5hbWUsIGV4dGVuc2lvbklkKSB7XG4gICAgdXBkYXRlSW50ZXJuYWxFeHRlbnNpb25TdG9yZSgoc3RhdGUpPT57XG4gICAgICAgIGNvbnN0IGV4aXN0aW5nU2xvdCA9IHN0YXRlLnNsb3RzW3Nsb3ROYW1lXTtcbiAgICAgICAgaWYgKCFleGlzdGluZ1Nsb3QpIHtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgLi4uc3RhdGUsXG4gICAgICAgICAgICAgICAgc2xvdHM6IHtcbiAgICAgICAgICAgICAgICAgICAgLi4uc3RhdGUuc2xvdHMsXG4gICAgICAgICAgICAgICAgICAgIFtzbG90TmFtZV06IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC4uLmNyZWF0ZU5ld0V4dGVuc2lvblNsb3RJbmZvKHNsb3ROYW1lKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGF0dGFjaGVkSWRzOiBbXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uSWRcbiAgICAgICAgICAgICAgICAgICAgICAgIF1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIC4uLnN0YXRlLFxuICAgICAgICAgICAgICAgIHNsb3RzOiB7XG4gICAgICAgICAgICAgICAgICAgIC4uLnN0YXRlLnNsb3RzLFxuICAgICAgICAgICAgICAgICAgICBbc2xvdE5hbWVdOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAuLi5leGlzdGluZ1Nsb3QsXG4gICAgICAgICAgICAgICAgICAgICAgICBhdHRhY2hlZElkczogW1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC4uLmV4aXN0aW5nU2xvdC5hdHRhY2hlZElkcyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25JZFxuICAgICAgICAgICAgICAgICAgICAgICAgXVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgIH0pO1xufVxuLyoqXG4gKiBAZGVwcmVjYXRlZCBBdm9pZCB1c2luZyB0aGlzLiBFeHRlbnNpb24gYXR0YWNobWVudHMgc2hvdWxkIGJlIGNvbnNpZGVyZWQgZGVjbGFyYXRpdmUuXG4gKi8gZXhwb3J0IGZ1bmN0aW9uIGRldGFjaChleHRlbnNpb25TbG90TmFtZSwgZXh0ZW5zaW9uSWQpIHtcbiAgICB1cGRhdGVJbnRlcm5hbEV4dGVuc2lvblN0b3JlKChzdGF0ZSk9PntcbiAgICAgICAgY29uc3QgZXhpc3RpbmdTbG90ID0gc3RhdGUuc2xvdHNbZXh0ZW5zaW9uU2xvdE5hbWVdO1xuICAgICAgICBpZiAoZXhpc3RpbmdTbG90ICYmIGV4aXN0aW5nU2xvdC5hdHRhY2hlZElkcy5pbmNsdWRlcyhleHRlbnNpb25JZCkpIHtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgLi4uc3RhdGUsXG4gICAgICAgICAgICAgICAgc2xvdHM6IHtcbiAgICAgICAgICAgICAgICAgICAgLi4uc3RhdGUuc2xvdHMsXG4gICAgICAgICAgICAgICAgICAgIFtleHRlbnNpb25TbG90TmFtZV06IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC4uLmV4aXN0aW5nU2xvdCxcbiAgICAgICAgICAgICAgICAgICAgICAgIGF0dGFjaGVkSWRzOiBleGlzdGluZ1Nsb3QuYXR0YWNoZWRJZHMuZmlsdGVyKChpZCk9PmlkICE9PSBleHRlbnNpb25JZClcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gc3RhdGU7XG4gICAgICAgIH1cbiAgICB9KTtcbn1cbi8qKlxuICogQGRlcHJlY2F0ZWQgQXZvaWQgdXNpbmcgdGhpcy4gRXh0ZW5zaW9uIGF0dGFjaG1lbnRzIHNob3VsZCBiZSBjb25zaWRlcmVkIGRlY2xhcmF0aXZlLlxuICovIGV4cG9ydCBmdW5jdGlvbiBkZXRhY2hBbGwoZXh0ZW5zaW9uU2xvdE5hbWUpIHtcbiAgICB1cGRhdGVJbnRlcm5hbEV4dGVuc2lvblN0b3JlKChzdGF0ZSk9PntcbiAgICAgICAgY29uc3QgZXhpc3RpbmdTbG90ID0gc3RhdGUuc2xvdHNbZXh0ZW5zaW9uU2xvdE5hbWVdO1xuICAgICAgICBpZiAoZXhpc3RpbmdTbG90KSB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIC4uLnN0YXRlLFxuICAgICAgICAgICAgICAgIHNsb3RzOiB7XG4gICAgICAgICAgICAgICAgICAgIC4uLnN0YXRlLnNsb3RzLFxuICAgICAgICAgICAgICAgICAgICBbZXh0ZW5zaW9uU2xvdE5hbWVdOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAuLi5leGlzdGluZ1Nsb3QsXG4gICAgICAgICAgICAgICAgICAgICAgICBhdHRhY2hlZElkczogW11cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gc3RhdGU7XG4gICAgICAgIH1cbiAgICB9KTtcbn1cbi8qKlxuICogR2V0IGFuIG9yZGVyIGluZGV4IGZvciB0aGUgZXh0ZW5zaW9uLiBUaGlzIHdpbGxcbiAqIGNvbWUgZnJvbSBlaXRoZXIgaXRzIGNvbmZpZ3VyZWQgb3JkZXIsIGl0cyByZWdpc3RlcmVkIG9yZGVyXG4gKiBwYXJhbWV0ZXIsIG9yIHRoZSBvcmRlciBpbiB3aGljaCBpdCBoYXBwZW5lZCB0byBiZSBhdHRhY2hlZC5cbiAqLyBmdW5jdGlvbiBnZXRPcmRlcihleHRlbnNpb25JZCwgY29uZmlndXJlZE9yZGVyLCByZWdpc3RlcmVkT3JkZXJJbmRleCwgYXR0YWNoZWRPcmRlcikge1xuICAgIGNvbnN0IGNvbmZpZ3VyZWRJbmRleCA9IGNvbmZpZ3VyZWRPcmRlci5pbmRleE9mKGV4dGVuc2lvbklkKTtcbiAgICBpZiAoY29uZmlndXJlZEluZGV4ICE9PSAtMSkge1xuICAgICAgICByZXR1cm4gY29uZmlndXJlZEluZGV4O1xuICAgIH0gZWxzZSBpZiAocmVnaXN0ZXJlZE9yZGVySW5kZXggIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAvLyBleHRlbnNpb25zIHRoYXQgZG9uJ3QgaGF2ZSBhIGNvbmZpZ3VyZWQgb3JkZXIgc2hvdWxkIGFwcGVhciBhZnRlciB0aG9zZSB0aGF0IGRvXG4gICAgICAgIHJldHVybiAxMDAwICsgcmVnaXN0ZXJlZE9yZGVySW5kZXg7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3QgYXNzaWduZWRJbmRleCA9IGF0dGFjaGVkT3JkZXIuaW5kZXhPZihleHRlbnNpb25JZCk7XG4gICAgICAgIGlmIChhc3NpZ25lZEluZGV4ICE9PSAtMSkge1xuICAgICAgICAgICAgLy8gZXh0ZW5zaW9ucyB0aGF0IGhhdmUgbmVpdGhlciBhIGNvbmZpZ3VyZWQgbm9yIHJlZ2lzdGVyZWQgb3JkZXIgc2hvdWxkIGFwcGVhclxuICAgICAgICAgICAgLy8gYWZ0ZXIgYWxsIG90aGVyc1xuICAgICAgICAgICAgcmV0dXJuIDIwMDAgKyBhc3NpZ25lZEluZGV4O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIC0xO1xuICAgICAgICB9XG4gICAgfVxufVxuZnVuY3Rpb24gZ2V0QXNzaWduZWRFeHRlbnNpb25zRnJvbVNsb3REYXRhKHNsb3ROYW1lLCBpbnRlcm5hbFN0YXRlLCBjb25maWcsIGV4dGVuc2lvbkNvbmZpZ1N0b3JlU3RhdGUsIGVuYWJsZWRGZWF0dXJlRmxhZ3MsIGlzT25saW5lLCBzZXNzaW9uKSB7XG4gICAgY29uc3QgYXR0YWNoZWRJZHMgPSBpbnRlcm5hbFN0YXRlLnNsb3RzW3Nsb3ROYW1lXS5hdHRhY2hlZElkcztcbiAgICBjb25zdCBhc3NpZ25lZElkcyA9IGNhbGN1bGF0ZUFzc2lnbmVkSWRzKGNvbmZpZywgYXR0YWNoZWRJZHMpO1xuICAgIGNvbnN0IGV4dGVuc2lvbnMgPSBbXTtcbiAgICAvLyBDcmVhdGUgY29udGV4dCBvbmNlIGZvciBhbGwgZXh0ZW5zaW9ucyBpbiB0aGlzIHNsb3RcbiAgICBjb25zdCBzbG90U3RhdGUgPSBpbnRlcm5hbFN0YXRlLnNsb3RzW3Nsb3ROYW1lXT8uc3RhdGU7XG4gICAgY29uc3QgZXhwcmVzc2lvbkNvbnRleHQgPSBzbG90U3RhdGUgJiYgdHlwZW9mIHNsb3RTdGF0ZSA9PT0gJ29iamVjdCcgPyB7XG4gICAgICAgIHNlc3Npb24sXG4gICAgICAgIC4uLnNsb3RTdGF0ZVxuICAgIH0gOiB7XG4gICAgICAgIHNlc3Npb25cbiAgICB9O1xuICAgIGZvciAobGV0IGlkIG9mIGFzc2lnbmVkSWRzKXtcbiAgICAgICAgY29uc3QgeyBjb25maWc6IHJhd0V4dGVuc2lvbkNvbmZpZyB9ID0gZ2V0RXh0ZW5zaW9uQ29uZmlnRnJvbVN0b3JlKGV4dGVuc2lvbkNvbmZpZ1N0b3JlU3RhdGUsIHNsb3ROYW1lLCBpZCk7XG4gICAgICAgIGNvbnN0IHJhd0V4dGVuc2lvblNsb3RFeHRlbnNpb25Db25maWcgPSBnZXRFeHRlbnNpb25Db25maWdGcm9tRXh0ZW5zaW9uU2xvdFN0b3JlKGNvbmZpZywgc2xvdE5hbWUsIGlkKTtcbiAgICAgICAgY29uc3QgZXh0ZW5zaW9uQ29uZmlnID0gbWVyZ2UocmF3RXh0ZW5zaW9uQ29uZmlnLCByYXdFeHRlbnNpb25TbG90RXh0ZW5zaW9uQ29uZmlnKTtcbiAgICAgICAgY29uc3QgbmFtZSA9IGdldEV4dGVuc2lvbk5hbWVGcm9tSWQoaWQpO1xuICAgICAgICBjb25zdCBleHRlbnNpb24gPSBpbnRlcm5hbFN0YXRlLmV4dGVuc2lvbnNbbmFtZV07XG4gICAgICAgIC8vIGlmIHRoZSBleHRlbnNpb24gaGFzIG5vdCBiZWVuIHJlZ2lzdGVyZWQgeWV0LCBkbyBub3QgaW5jbHVkZSBpdFxuICAgICAgICBpZiAoZXh0ZW5zaW9uKSB7XG4gICAgICAgICAgICBjb25zdCByZXF1aXJlZFByaXZpbGVnZXMgPSBleHRlbnNpb25Db25maWc/LlsnRGlzcGxheSBjb25kaXRpb25zJ10/LnByaXZpbGVnZXMgPz8gZXh0ZW5zaW9uLnByaXZpbGVnZXMgPz8gW107XG4gICAgICAgICAgICBpZiAocmVxdWlyZWRQcml2aWxlZ2VzICYmICh0eXBlb2YgcmVxdWlyZWRQcml2aWxlZ2VzID09PSAnc3RyaW5nJyB8fCBBcnJheS5pc0FycmF5KHJlcXVpcmVkUHJpdmlsZWdlcykgJiYgcmVxdWlyZWRQcml2aWxlZ2VzLmxlbmd0aCA+IDApKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFzZXNzaW9uPy51c2VyKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoIXVzZXJIYXNBY2Nlc3MocmVxdWlyZWRQcml2aWxlZ2VzLCBzZXNzaW9uLnVzZXIpKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IGRpc3BsYXlDb25kaXRpb25FeHByZXNzaW9uID0gZXh0ZW5zaW9uQ29uZmlnPy5bJ0Rpc3BsYXkgY29uZGl0aW9ucyddPy5leHByZXNzaW9uIHx8IGV4dGVuc2lvbi5kaXNwbGF5RXhwcmVzc2lvbjtcbiAgICAgICAgICAgIGlmIChkaXNwbGF5Q29uZGl0aW9uRXhwcmVzc2lvbiAhPT0gdW5kZWZpbmVkICYmIHR5cGVvZiBkaXNwbGF5Q29uZGl0aW9uRXhwcmVzc2lvbiA9PT0gJ3N0cmluZycgJiYgZGlzcGxheUNvbmRpdGlvbkV4cHJlc3Npb24udHJpbSgpLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoIWV2YWx1YXRlQXNCb29sZWFuKGRpc3BsYXlDb25kaXRpb25FeHByZXNzaW9uLCBleHByZXNzaW9uQ29udGV4dCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKGBFcnJvciB3aGlsZSBldmFsdWF0aW5nIGV4cHJlc3Npb24gJyR7ZGlzcGxheUNvbmRpdGlvbkV4cHJlc3Npb259JyBmb3IgZXh0ZW5zaW9uICR7bmFtZX0gaW4gc2xvdCAke3Nsb3ROYW1lfWAsIGUpO1xuICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoZXh0ZW5zaW9uLmZlYXR1cmVGbGFnICYmICFlbmFibGVkRmVhdHVyZUZsYWdzLmluY2x1ZGVzKGV4dGVuc2lvbi5mZWF0dXJlRmxhZykpIHtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh3aW5kb3cub2ZmbGluZUVuYWJsZWQgJiYgIWNoZWNrU3RhdHVzRm9yKGlzT25saW5lLCBleHRlbnNpb24ub25saW5lLCBleHRlbnNpb24ub2ZmbGluZSkpIHtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGV4dGVuc2lvbnMucHVzaCh7XG4gICAgICAgICAgICAgICAgaWQsXG4gICAgICAgICAgICAgICAgbmFtZSxcbiAgICAgICAgICAgICAgICBtb2R1bGVOYW1lOiBleHRlbnNpb24ubW9kdWxlTmFtZSxcbiAgICAgICAgICAgICAgICBjb25maWc6IGV4dGVuc2lvbkNvbmZpZyxcbiAgICAgICAgICAgICAgICBmZWF0dXJlRmxhZzogZXh0ZW5zaW9uLmZlYXR1cmVGbGFnLFxuICAgICAgICAgICAgICAgIG1ldGE6IGV4dGVuc2lvbi5tZXRhLFxuICAgICAgICAgICAgICAgIG9ubGluZTogZXh0ZW5zaW9uQ29uZmlnPy5bJ0Rpc3BsYXkgY29uZGl0aW9ucyddPy5vbmxpbmUgPz8gZXh0ZW5zaW9uLm9ubGluZSA/PyB0cnVlLFxuICAgICAgICAgICAgICAgIG9mZmxpbmU6IGV4dGVuc2lvbkNvbmZpZz8uWydEaXNwbGF5IGNvbmRpdGlvbnMnXT8ub2ZmbGluZSA/PyBleHRlbnNpb24ub2ZmbGluZSA/PyBmYWxzZVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGV4dGVuc2lvbnM7XG59XG4vKipcbiAqIEdldHMgdGhlIGxpc3Qgb2YgZXh0ZW5zaW9ucyBhc3NpZ25lZCB0byBhIGdpdmVuIHNsb3RcbiAqXG4gKiBAcGFyYW0gc2xvdE5hbWUgVGhlIHNsb3QgdG8gbG9hZCB0aGUgYXNzaWduZWQgZXh0ZW5zaW9ucyBmb3JcbiAqIEByZXR1cm5zIEFuIGFycmF5IG9mIGV4dGVuc2lvbnMgYXNzaWduZWQgdG8gdGhlIG5hbWVkIHNsb3RcbiAqLyBleHBvcnQgZnVuY3Rpb24gZ2V0QXNzaWduZWRFeHRlbnNpb25zKHNsb3ROYW1lKSB7XG4gICAgY29uc3QgaW50ZXJuYWxTdGF0ZSA9IGV4dGVuc2lvbkludGVybmFsU3RvcmUuZ2V0U3RhdGUoKTtcbiAgICBjb25zdCB7IGNvbmZpZzogc2xvdENvbmZpZyB9ID0gZ2V0RXh0ZW5zaW9uU2xvdENvbmZpZyhzbG90TmFtZSk7XG4gICAgY29uc3QgZXh0ZW5zaW9uU3RvcmVTdGF0ZSA9IGV4dGVuc2lvbnNDb25maWdTdG9yZS5nZXRTdGF0ZSgpO1xuICAgIGNvbnN0IGZlYXR1cmVGbGFnU3RhdGUgPSBmZWF0dXJlRmxhZ3NTdG9yZS5nZXRTdGF0ZSgpO1xuICAgIGNvbnN0IHNlc3Npb25TdGF0ZSA9IHNlc3Npb25TdG9yZS5nZXRTdGF0ZSgpO1xuICAgIGNvbnN0IGlzT25saW5lID0gaXNPbmxpbmVGbigpO1xuICAgIGNvbnN0IGVuYWJsZWRGZWF0dXJlRmxhZ3MgPSBPYmplY3QuZW50cmllcyhmZWF0dXJlRmxhZ1N0YXRlLmZsYWdzKS5maWx0ZXIoKFssIHsgZW5hYmxlZCB9XSk9PmVuYWJsZWQpLm1hcCgoW25hbWVdKT0+bmFtZSk7XG4gICAgcmV0dXJuIGdldEFzc2lnbmVkRXh0ZW5zaW9uc0Zyb21TbG90RGF0YShzbG90TmFtZSwgaW50ZXJuYWxTdGF0ZSwgc2xvdENvbmZpZywgZXh0ZW5zaW9uU3RvcmVTdGF0ZSwgZW5hYmxlZEZlYXR1cmVGbGFncywgaXNPbmxpbmUsIHNlc3Npb25TdGF0ZS5zZXNzaW9uKTtcbn1cbmZ1bmN0aW9uIGNhbGN1bGF0ZUFzc2lnbmVkSWRzKGNvbmZpZywgYXR0YWNoZWRJZHMpIHtcbiAgICBjb25zdCBhZGRlZElkcyA9IGNvbmZpZy5hZGQgfHwgW107XG4gICAgY29uc3QgcmVtb3ZlZElkcyA9IGNvbmZpZy5yZW1vdmUgfHwgW107XG4gICAgY29uc3QgaWRPcmRlciA9IGNvbmZpZy5vcmRlciB8fCBbXTtcbiAgICBjb25zdCB7IGV4dGVuc2lvbnMgfSA9IGV4dGVuc2lvbkludGVybmFsU3RvcmUuZ2V0U3RhdGUoKTtcbiAgICByZXR1cm4gW1xuICAgICAgICAuLi5hdHRhY2hlZElkcyxcbiAgICAgICAgLi4uYWRkZWRJZHNcbiAgICBdLmZpbHRlcigoaWQpPT4hcmVtb3ZlZElkcy5pbmNsdWRlcyhpZCkpLnNvcnQoKGlkQSwgaWRCKT0+e1xuICAgICAgICBjb25zdCBhaSA9IGdldE9yZGVyKGlkQSwgaWRPcmRlciwgZXh0ZW5zaW9uc1tnZXRFeHRlbnNpb25OYW1lRnJvbUlkKGlkQSldPy5vcmRlciwgYXR0YWNoZWRJZHMpO1xuICAgICAgICBjb25zdCBiaSA9IGdldE9yZGVyKGlkQiwgaWRPcmRlciwgZXh0ZW5zaW9uc1tnZXRFeHRlbnNpb25OYW1lRnJvbUlkKGlkQildPy5vcmRlciwgYXR0YWNoZWRJZHMpO1xuICAgICAgICBpZiAoYmkgPT09IC0xKSB7XG4gICAgICAgICAgICByZXR1cm4gLTE7XG4gICAgICAgIH0gZWxzZSBpZiAoYWkgPT09IC0xKSB7XG4gICAgICAgICAgICByZXR1cm4gMTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBhaSAtIGJpO1xuICAgICAgICB9XG4gICAgfSk7XG59XG4vKipcbiAqIFVzZWQgYnkgYnkgZXh0ZW5zaW9uIHNsb3RzIGF0IG1vdW50IHRpbWUuXG4gKlxuICogQHBhcmFtIG1vZHVsZU5hbWUgVGhlIG5hbWUgb2YgdGhlIG1vZHVsZSB0aGF0IGNvbnRhaW5zIHRoZSBleHRlbnNpb24gc2xvdFxuICogQHBhcmFtIHNsb3ROYW1lIFRoZSBleHRlbnNpb24gc2xvdCBuYW1lIHRoYXQgaXMgYWN0dWFsbHkgdXNlZFxuICogQHBhcmFtIHN0YXRlIE9wdGlvbmFsIGN1c3RvbSBzdGF0ZSBmb3IgdGhlIHNsb3QsIHdoaWNoIHdpbGwgYmUgc3RvcmVkIGluIHRoZSBleHRlbnNpb24gc3RvcmUuXG4gKiBAaW50ZXJuYWxcbiAqLyBleHBvcnQgY29uc3QgcmVnaXN0ZXJFeHRlbnNpb25TbG90ID0gKG1vZHVsZU5hbWUsIHNsb3ROYW1lLCBzdGF0ZSk9PmV4dGVuc2lvbkludGVybmFsU3RvcmUuc2V0U3RhdGUoKGN1cnJlbnRTdGF0ZSk9PntcbiAgICAgICAgY29uc3QgZXhpc3RpbmdNb2R1bGVOYW1lID0gY3VycmVudFN0YXRlLnNsb3RzW3Nsb3ROYW1lXT8ubW9kdWxlTmFtZTtcbiAgICAgICAgaWYgKGV4aXN0aW5nTW9kdWxlTmFtZSAmJiBleGlzdGluZ01vZHVsZU5hbWUgIT0gbW9kdWxlTmFtZSkge1xuICAgICAgICAgICAgY29uc29sZS53YXJuKGBBbiBleHRlbnNpb24gc2xvdCB3aXRoIHRoZSBuYW1lICcke3Nsb3ROYW1lfScgYWxyZWFkeSBleGlzdHMuIFJlZnVzaW5nIHRvIHJlZ2lzdGVyIHRoZSBzYW1lIHNsb3QgbmFtZSB0d2ljZSAoaW4gXCJyZWdpc3RlckV4dGVuc2lvblNsb3RcIikuIFRoZSBleGlzdGluZyBvbmUgaXMgZnJvbSBtb2R1bGUgJHtleGlzdGluZ01vZHVsZU5hbWV9LmApO1xuICAgICAgICAgICAgcmV0dXJuIGN1cnJlbnRTdGF0ZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZXhpc3RpbmdNb2R1bGVOYW1lICYmIGV4aXN0aW5nTW9kdWxlTmFtZSA9PSBtb2R1bGVOYW1lKSB7XG4gICAgICAgICAgICAvLyBSZS1yZW5kZXJpbmcgYW4gZXhpc3Rpbmcgc2xvdFxuICAgICAgICAgICAgcmV0dXJuIGN1cnJlbnRTdGF0ZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoY3VycmVudFN0YXRlLnNsb3RzW3Nsb3ROYW1lXSkge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAuLi5jdXJyZW50U3RhdGUsXG4gICAgICAgICAgICAgICAgc2xvdHM6IHtcbiAgICAgICAgICAgICAgICAgICAgLi4uY3VycmVudFN0YXRlLnNsb3RzLFxuICAgICAgICAgICAgICAgICAgICBbc2xvdE5hbWVdOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAuLi5jdXJyZW50U3RhdGUuc2xvdHNbc2xvdE5hbWVdLFxuICAgICAgICAgICAgICAgICAgICAgICAgbW9kdWxlTmFtZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0YXRlXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHNsb3QgPSBjcmVhdGVOZXdFeHRlbnNpb25TbG90SW5mbyhzbG90TmFtZSwgbW9kdWxlTmFtZSwgc3RhdGUpO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgLi4uY3VycmVudFN0YXRlLFxuICAgICAgICAgICAgc2xvdHM6IHtcbiAgICAgICAgICAgICAgICAuLi5jdXJyZW50U3RhdGUuc2xvdHMsXG4gICAgICAgICAgICAgICAgW3Nsb3ROYW1lXToge1xuICAgICAgICAgICAgICAgICAgICAuLi5zbG90XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH0pO1xuLyoqXG4gKiBVc2VkIGJ5IGV4dGVuc2lvbiBzbG90cyB0byB1cGRhdGUgdGhlIGNvcHkgb2YgdGhlIHN0YXRlIGZvciB0aGUgZXh0ZW5zaW9uIHNsb3RcbiAqXG4gKiBAcGFyYW0gc2xvdE5hbWUgVGhlIG5hbWUgb2YgdGhlIHNsb3Qgd2l0aCBzdGF0ZSB0byB1cGRhdGVcbiAqIEBwYXJhbSBzdGF0ZSBBIGNvcHkgb2YgdGhlIG5ldyBzdGF0ZVxuICogQHBhcmFtIHBhcnRpYWwgV2hldGhlciB0aGlzIHNob3VsZCBiZSBhcHBsaWVkIGFzIGEgcGFydGlhbFxuICovIGV4cG9ydCBmdW5jdGlvbiB1cGRhdGVFeHRlbnNpb25TbG90U3RhdGUoc2xvdE5hbWUsIHN0YXRlLCBwYXJ0aWFsID0gZmFsc2UpIHtcbiAgICBleHRlbnNpb25JbnRlcm5hbFN0b3JlLnNldFN0YXRlKChjdXJyZW50U3RhdGUpPT57XG4gICAgICAgIGNvbnN0IG5ld1N0YXRlID0gcGFydGlhbCA/IG1lcmdlKGN1cnJlbnRTdGF0ZS5zbG90c1tzbG90TmFtZV0uc3RhdGUsIHN0YXRlKSA6IHN0YXRlO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgLi4uY3VycmVudFN0YXRlLFxuICAgICAgICAgICAgc2xvdHM6IHtcbiAgICAgICAgICAgICAgICAuLi5jdXJyZW50U3RhdGUuc2xvdHMsXG4gICAgICAgICAgICAgICAgW3Nsb3ROYW1lXToge1xuICAgICAgICAgICAgICAgICAgICAuLi5jdXJyZW50U3RhdGUuc2xvdHNbc2xvdE5hbWVdLFxuICAgICAgICAgICAgICAgICAgICBzdGF0ZTogbmV3U3RhdGVcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfSk7XG59XG4vKipcbiAqIEBpbnRlcm5hbFxuICogSnVzdCBmb3IgdGVzdGluZy5cbiAqLyBleHBvcnQgY29uc3QgcmVzZXQgPSAoKT0+ZXh0ZW5zaW9uU3RvcmUuc2V0U3RhdGUoKCk9PntcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHNsb3RzOiB7fSxcbiAgICAgICAgICAgIGV4dGVuc2lvbnM6IHt9XG4gICAgICAgIH07XG4gICAgfSk7XG4iXSwibmFtZXMiOlsic2Vzc2lvblN0b3JlIiwidXNlckhhc0FjY2VzcyIsImdldEV4dGVuc2lvbkNvbmZpZ0Zyb21FeHRlbnNpb25TbG90U3RvcmUiLCJnZXRFeHRlbnNpb25Db25maWdGcm9tU3RvcmUiLCJnZXRFeHRlbnNpb25TbG90Q29uZmlnIiwiZ2V0RXh0ZW5zaW9uU2xvdENvbmZpZ0Zyb21TdG9yZSIsImdldEV4dGVuc2lvblNsb3RzQ29uZmlnU3RvcmUiLCJnZXRFeHRlbnNpb25zQ29uZmlnU3RvcmUiLCJldmFsdWF0ZUFzQm9vbGVhbiIsImZlYXR1cmVGbGFnc1N0b3JlIiwic3Vic2NyaWJlQ29ubmVjdGl2aXR5Q2hhbmdlZCIsImlzT25saW5lIiwiaXNPbmxpbmVGbiIsImlzRXF1YWwiLCJtZXJnZSIsImNoZWNrU3RhdHVzRm9yIiwiZ2V0RXh0ZW5zaW9uSW50ZXJuYWxTdG9yZSIsImdldEV4dGVuc2lvblN0b3JlIiwidXBkYXRlSW50ZXJuYWxFeHRlbnNpb25TdG9yZSIsImV4dGVuc2lvbkludGVybmFsU3RvcmUiLCJleHRlbnNpb25TdG9yZSIsInNsb3RzQ29uZmlnU3RvcmUiLCJleHRlbnNpb25zQ29uZmlnU3RvcmUiLCJ1cGRhdGVFeHRlbnNpb25PdXRwdXRTdG9yZSIsImludGVybmFsU3RhdGUiLCJleHRlbnNpb25TbG90Q29uZmlncyIsImZlYXR1cmVGbGFnU3RvcmUiLCJzbG90cyIsImVuYWJsZWRGZWF0dXJlRmxhZ3MiLCJPYmplY3QiLCJlbnRyaWVzIiwiZmxhZ3MiLCJmaWx0ZXIiLCJlbmFibGVkIiwibWFwIiwibmFtZSIsInNsb3ROYW1lIiwic2xvdCIsImNvbmZpZyIsImFzc2lnbmVkRXh0ZW5zaW9ucyIsImdldEFzc2lnbmVkRXh0ZW5zaW9uc0Zyb21TbG90RGF0YSIsInNlc3Npb24iLCJtb2R1bGVOYW1lIiwiZ2V0U3RhdGUiLCJzZXRTdGF0ZSIsInN1YnNjcmliZSIsImludGVybmFsU3RvcmUiLCJzbG90Q29uZmlncyIsImV4dGVuc2lvbkNvbmZpZ3MiLCJ1cGRhdGVPdXRwdXRTdG9yZVRvQ3VycmVudCIsImNyZWF0ZU5ld0V4dGVuc2lvblNsb3RJbmZvIiwic3RhdGUiLCJhdHRhY2hlZElkcyIsImdldEV4dGVuc2lvbk5hbWVGcm9tSWQiLCJleHRlbnNpb25JZCIsImV4dGVuc2lvbk5hbWUiLCJzcGxpdCIsImdldEV4dGVuc2lvblJlZ2lzdHJhdGlvbkZyb20iLCJleHRlbnNpb25zIiwiZ2V0RXh0ZW5zaW9uUmVnaXN0cmF0aW9uIiwicmVnaXN0ZXJFeHRlbnNpb24iLCJleHRlbnNpb25SZWdpc3RyYXRpb24iLCJpbnN0YW5jZXMiLCJhdHRhY2giLCJleGlzdGluZ1Nsb3QiLCJkZXRhY2giLCJleHRlbnNpb25TbG90TmFtZSIsImluY2x1ZGVzIiwiaWQiLCJkZXRhY2hBbGwiLCJnZXRPcmRlciIsImNvbmZpZ3VyZWRPcmRlciIsInJlZ2lzdGVyZWRPcmRlckluZGV4IiwiYXR0YWNoZWRPcmRlciIsImNvbmZpZ3VyZWRJbmRleCIsImluZGV4T2YiLCJ1bmRlZmluZWQiLCJhc3NpZ25lZEluZGV4IiwiZXh0ZW5zaW9uQ29uZmlnU3RvcmVTdGF0ZSIsImFzc2lnbmVkSWRzIiwiY2FsY3VsYXRlQXNzaWduZWRJZHMiLCJzbG90U3RhdGUiLCJleHByZXNzaW9uQ29udGV4dCIsInJhd0V4dGVuc2lvbkNvbmZpZyIsInJhd0V4dGVuc2lvblNsb3RFeHRlbnNpb25Db25maWciLCJleHRlbnNpb25Db25maWciLCJleHRlbnNpb24iLCJyZXF1aXJlZFByaXZpbGVnZXMiLCJwcml2aWxlZ2VzIiwiQXJyYXkiLCJpc0FycmF5IiwibGVuZ3RoIiwidXNlciIsImRpc3BsYXlDb25kaXRpb25FeHByZXNzaW9uIiwiZXhwcmVzc2lvbiIsImRpc3BsYXlFeHByZXNzaW9uIiwidHJpbSIsImUiLCJjb25zb2xlIiwiZXJyb3IiLCJmZWF0dXJlRmxhZyIsIndpbmRvdyIsIm9mZmxpbmVFbmFibGVkIiwib25saW5lIiwib2ZmbGluZSIsInB1c2giLCJtZXRhIiwiZ2V0QXNzaWduZWRFeHRlbnNpb25zIiwic2xvdENvbmZpZyIsImV4dGVuc2lvblN0b3JlU3RhdGUiLCJmZWF0dXJlRmxhZ1N0YXRlIiwic2Vzc2lvblN0YXRlIiwiYWRkZWRJZHMiLCJhZGQiLCJyZW1vdmVkSWRzIiwicmVtb3ZlIiwiaWRPcmRlciIsIm9yZGVyIiwic29ydCIsImlkQSIsImlkQiIsImFpIiwiYmkiLCJyZWdpc3RlckV4dGVuc2lvblNsb3QiLCJjdXJyZW50U3RhdGUiLCJleGlzdGluZ01vZHVsZU5hbWUiLCJ3YXJuIiwidXBkYXRlRXh0ZW5zaW9uU2xvdFN0YXRlIiwicGFydGlhbCIsIm5ld1N0YXRlIiwicmVzZXQiXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///../../framework/esm-extensions/dist/extensions.js\n");
448
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ attach: () => (/* binding */ attach),\n/* harmony export */ detach: () => (/* binding */ detach),\n/* harmony export */ detachAll: () => (/* binding */ detachAll),\n/* harmony export */ getAssignedExtensions: () => (/* binding */ getAssignedExtensions),\n/* harmony export */ getExtensionNameFromId: () => (/* binding */ getExtensionNameFromId),\n/* harmony export */ getExtensionRegistration: () => (/* binding */ getExtensionRegistration),\n/* harmony export */ getExtensionRegistrationFrom: () => (/* binding */ getExtensionRegistrationFrom),\n/* harmony export */ registerExtension: () => (/* binding */ registerExtension),\n/* harmony export */ registerExtensionSlot: () => (/* binding */ registerExtensionSlot),\n/* harmony export */ reset: () => (/* binding */ reset),\n/* harmony export */ updateExtensionSlotState: () => (/* binding */ updateExtensionSlotState)\n/* harmony export */ });\n/* harmony import */ var _openmrs_esm_api__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @openmrs/esm-api */ \"../../framework/esm-api/dist/index.js\");\n/* harmony import */ var _openmrs_esm_config__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @openmrs/esm-config */ \"../../framework/esm-config/dist/index.js\");\n/* harmony import */ var _openmrs_esm_expression_evaluator__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! @openmrs/esm-expression-evaluator */ \"../../framework/esm-expression-evaluator/dist/evaluator.js\");\n/* harmony import */ var _openmrs_esm_feature_flags__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @openmrs/esm-feature-flags */ \"../../framework/esm-feature-flags/dist/index.js\");\n/* harmony import */ var _openmrs_esm_globals__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @openmrs/esm-globals */ \"../../framework/esm-globals/dist/index.js\");\n/* harmony import */ var _openmrs_esm_utils__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @openmrs/esm-utils */ \"../../framework/esm-utils/dist/is-online.js\");\n/* harmony import */ var lodash_es__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! lodash-es */ \"../../../node_modules/lodash-es/isEqual.js\");\n/* harmony import */ var lodash_es__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! lodash-es */ \"../../../node_modules/lodash-es/merge.js\");\n/* harmony import */ var _helpers_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./helpers.js */ \"../../framework/esm-extensions/dist/helpers.js\");\n/* harmony import */ var _store_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./store.js */ \"../../framework/esm-extensions/dist/store.js\");\n/** @module @category Extension */ /*\n * We have the following extension modes:\n *\n * - attached (set via code in form of: attach, detach, ...)\n * - configured (set via configuration in form of: added, removed, ...)\n * - assigned (computed from attached and configured)\n * - connected (computed from assigned using connectivity and online / offline)\n */ \n\n\n\n\n\n\n\n\nconst extensionInternalStore = (0,_store_js__WEBPACK_IMPORTED_MODULE_5__.getExtensionInternalStore)();\nconst extensionStore = (0,_store_js__WEBPACK_IMPORTED_MODULE_5__.getExtensionStore)();\nconst slotsConfigStore = (0,_openmrs_esm_config__WEBPACK_IMPORTED_MODULE_1__.getExtensionSlotsConfigStore)();\nconst extensionsConfigStore = (0,_openmrs_esm_config__WEBPACK_IMPORTED_MODULE_1__.getExtensionsConfigStore)();\n// Keep the output store updated\nfunction updateExtensionOutputStore(internalState, extensionSlotConfigs, extensionsConfigStore, featureFlagStore, sessionStore) {\n const slots = {};\n const isOnline = (0,_openmrs_esm_utils__WEBPACK_IMPORTED_MODULE_6__.isOnline)();\n const enabledFeatureFlags = Object.entries(featureFlagStore.flags).filter(([, { enabled }])=>enabled).map(([name])=>name);\n for (let [slotName, slot] of Object.entries(internalState.slots)){\n const { config } = (0,_openmrs_esm_config__WEBPACK_IMPORTED_MODULE_1__.getExtensionSlotConfigFromStore)(extensionSlotConfigs, slot.name);\n const assignedExtensions = getAssignedExtensionsFromSlotData(slotName, internalState, config, extensionsConfigStore, enabledFeatureFlags, isOnline, sessionStore.session);\n slots[slotName] = {\n moduleName: slot.moduleName,\n assignedExtensions\n };\n }\n if (!(0,lodash_es__WEBPACK_IMPORTED_MODULE_7__[\"default\"])(extensionStore.getState().slots, slots)) {\n extensionStore.setState({\n slots\n });\n }\n}\nextensionInternalStore.subscribe((internalStore)=>{\n updateExtensionOutputStore(internalStore, slotsConfigStore.getState(), extensionsConfigStore.getState(), _openmrs_esm_feature_flags__WEBPACK_IMPORTED_MODULE_2__.featureFlagsStore.getState(), _openmrs_esm_api__WEBPACK_IMPORTED_MODULE_0__.sessionStore.getState());\n});\nslotsConfigStore.subscribe((slotConfigs)=>{\n updateExtensionOutputStore(extensionInternalStore.getState(), slotConfigs, extensionsConfigStore.getState(), _openmrs_esm_feature_flags__WEBPACK_IMPORTED_MODULE_2__.featureFlagsStore.getState(), _openmrs_esm_api__WEBPACK_IMPORTED_MODULE_0__.sessionStore.getState());\n});\nextensionsConfigStore.subscribe((extensionConfigs)=>{\n updateExtensionOutputStore(extensionInternalStore.getState(), slotsConfigStore.getState(), extensionConfigs, _openmrs_esm_feature_flags__WEBPACK_IMPORTED_MODULE_2__.featureFlagsStore.getState(), _openmrs_esm_api__WEBPACK_IMPORTED_MODULE_0__.sessionStore.getState());\n});\n_openmrs_esm_feature_flags__WEBPACK_IMPORTED_MODULE_2__.featureFlagsStore.subscribe((featureFlagStore)=>{\n updateExtensionOutputStore(extensionInternalStore.getState(), slotsConfigStore.getState(), extensionsConfigStore.getState(), featureFlagStore, _openmrs_esm_api__WEBPACK_IMPORTED_MODULE_0__.sessionStore.getState());\n});\n_openmrs_esm_api__WEBPACK_IMPORTED_MODULE_0__.sessionStore.subscribe((session)=>{\n updateExtensionOutputStore(extensionInternalStore.getState(), slotsConfigStore.getState(), extensionsConfigStore.getState(), _openmrs_esm_feature_flags__WEBPACK_IMPORTED_MODULE_2__.featureFlagsStore.getState(), session);\n});\nfunction updateOutputStoreToCurrent() {\n updateExtensionOutputStore(extensionInternalStore.getState(), slotsConfigStore.getState(), extensionsConfigStore.getState(), _openmrs_esm_feature_flags__WEBPACK_IMPORTED_MODULE_2__.featureFlagsStore.getState(), _openmrs_esm_api__WEBPACK_IMPORTED_MODULE_0__.sessionStore.getState());\n}\nupdateOutputStoreToCurrent();\n(0,_openmrs_esm_globals__WEBPACK_IMPORTED_MODULE_3__.subscribeConnectivityChanged)(updateOutputStoreToCurrent);\nfunction createNewExtensionSlotInfo(slotName, moduleName, state) {\n return {\n moduleName,\n name: slotName,\n attachedIds: [],\n config: null,\n state\n };\n}\n/**\n * Given an extension ID, which is a string uniquely identifying\n * an instance of an extension within an extension slot, this\n * returns the extension name.\n *\n * @example\n * ```js\n * getExtensionNameFromId(\"foo#bar\")\n * --> \"foo\"\n * getExtensionNameFromId(\"baz\")\n * --> \"baz\"\n * ```\n */ function getExtensionNameFromId(extensionId) {\n const [extensionName] = extensionId.split('#');\n return extensionName;\n}\nfunction getExtensionRegistrationFrom(state, extensionId) {\n const name = getExtensionNameFromId(extensionId);\n return state.extensions[name];\n}\nfunction getExtensionRegistration(extensionId) {\n const state = extensionInternalStore.getState();\n return getExtensionRegistrationFrom(state, extensionId);\n}\n/**\n * Extensions must be registered in order to be rendered.\n * This is handled by the app shell, when extensions are provided\n * via the `routes.json` file and registered through `registerApp()`.\n * @internal\n */ const registerExtension = (extensionRegistration)=>extensionInternalStore.setState((state)=>{\n state.extensions[extensionRegistration.name] = {\n ...extensionRegistration,\n instances: []\n };\n return state;\n });\n/**\n * Attach an extension to an extension slot.\n *\n * This will cause the extension to be rendered into the specified\n * extension slot, unless it is removed by configuration. Using\n * `attach` is an alternative to specifying the `slot` or `slots`\n * in the extension declaration.\n *\n * It is particularly useful when creating a slot into which\n * you want to render an existing extension. This enables you\n * to do so without modifying the extension's declaration, which\n * may be impractical or inappropriate, for example if you are\n * writing a module for a specific implementation.\n *\n * @param slotName a name uniquely identifying the slot\n * @param extensionId an extension name, with an optional #-suffix\n * to distinguish it from other instances of the same extension\n * attached to the same slot.\n */ function attach(slotName, extensionId) {\n (0,_store_js__WEBPACK_IMPORTED_MODULE_5__.updateInternalExtensionStore)((state)=>{\n const existingSlot = state.slots[slotName];\n if (!existingSlot) {\n return {\n ...state,\n slots: {\n ...state.slots,\n [slotName]: {\n ...createNewExtensionSlotInfo(slotName),\n attachedIds: [\n extensionId\n ]\n }\n }\n };\n } else {\n return {\n ...state,\n slots: {\n ...state.slots,\n [slotName]: {\n ...existingSlot,\n attachedIds: [\n ...existingSlot.attachedIds,\n extensionId\n ]\n }\n }\n };\n }\n });\n}\n/**\n * @deprecated Avoid using this. Extension attachments should be considered declarative.\n */ function detach(extensionSlotName, extensionId) {\n (0,_store_js__WEBPACK_IMPORTED_MODULE_5__.updateInternalExtensionStore)((state)=>{\n const existingSlot = state.slots[extensionSlotName];\n if (existingSlot && existingSlot.attachedIds.includes(extensionId)) {\n return {\n ...state,\n slots: {\n ...state.slots,\n [extensionSlotName]: {\n ...existingSlot,\n attachedIds: existingSlot.attachedIds.filter((id)=>id !== extensionId)\n }\n }\n };\n } else {\n return state;\n }\n });\n}\n/**\n * @deprecated Avoid using this. Extension attachments should be considered declarative.\n */ function detachAll(extensionSlotName) {\n (0,_store_js__WEBPACK_IMPORTED_MODULE_5__.updateInternalExtensionStore)((state)=>{\n const existingSlot = state.slots[extensionSlotName];\n if (existingSlot) {\n return {\n ...state,\n slots: {\n ...state.slots,\n [extensionSlotName]: {\n ...existingSlot,\n attachedIds: []\n }\n }\n };\n } else {\n return state;\n }\n });\n}\n/**\n * Get an order index for the extension. This will\n * come from either its configured order, its registered order\n * parameter, or the order in which it happened to be attached.\n */ function getOrder(extensionId, configuredOrder, registeredOrderIndex, attachedOrder) {\n const configuredIndex = configuredOrder.indexOf(extensionId);\n if (configuredIndex !== -1) {\n return configuredIndex;\n } else if (registeredOrderIndex !== undefined) {\n // extensions that don't have a configured order should appear after those that do\n return 1000 + registeredOrderIndex;\n } else {\n const assignedIndex = attachedOrder.indexOf(extensionId);\n if (assignedIndex !== -1) {\n // extensions that have neither a configured nor registered order should appear\n // after all others\n return 2000 + assignedIndex;\n } else {\n return -1;\n }\n }\n}\nfunction getAssignedExtensionsFromSlotData(slotName, internalState, config, extensionConfigStoreState, enabledFeatureFlags, isOnline, session) {\n const attachedIds = internalState.slots[slotName].attachedIds;\n const assignedIds = calculateAssignedIds(config, attachedIds);\n const extensions = [];\n // Create context once for all extensions in this slot\n const slotState = internalState.slots[slotName]?.state;\n const expressionContext = slotState && typeof slotState === 'object' ? {\n session,\n ...slotState\n } : {\n session\n };\n for (let id of assignedIds){\n const { config: rawExtensionConfig } = (0,_openmrs_esm_config__WEBPACK_IMPORTED_MODULE_1__.getExtensionConfigFromStore)(extensionConfigStoreState, slotName, id);\n const rawExtensionSlotExtensionConfig = (0,_openmrs_esm_config__WEBPACK_IMPORTED_MODULE_1__.getExtensionConfigFromExtensionSlotStore)(config, slotName, id);\n const extensionConfig = (0,lodash_es__WEBPACK_IMPORTED_MODULE_8__[\"default\"])(rawExtensionConfig, rawExtensionSlotExtensionConfig);\n const name = getExtensionNameFromId(id);\n const extension = internalState.extensions[name];\n // if the extension has not been registered yet, do not include it\n if (extension) {\n const requiredPrivileges = extensionConfig?.['Display conditions']?.privileges ?? extension.privileges ?? [];\n if (requiredPrivileges && (typeof requiredPrivileges === 'string' || Array.isArray(requiredPrivileges) && requiredPrivileges.length > 0)) {\n if (!session?.user) {\n continue;\n }\n if (!(0,_openmrs_esm_api__WEBPACK_IMPORTED_MODULE_0__.userHasAccess)(requiredPrivileges, session.user)) {\n continue;\n }\n }\n const displayConditionExpression = extensionConfig?.['Display conditions']?.expression || extension.displayExpression;\n if (displayConditionExpression !== undefined && typeof displayConditionExpression === 'string' && displayConditionExpression.trim().length > 0) {\n try {\n if (!(0,_openmrs_esm_expression_evaluator__WEBPACK_IMPORTED_MODULE_9__.evaluateAsBoolean)(displayConditionExpression, expressionContext)) {\n continue;\n }\n } catch (e) {\n console.error(`Error while evaluating expression '${displayConditionExpression}' for extension ${name} in slot ${slotName}`, e);\n continue;\n }\n }\n if (extension.featureFlag && !enabledFeatureFlags.includes(extension.featureFlag)) {\n continue;\n }\n if (window.offlineEnabled && !(0,_helpers_js__WEBPACK_IMPORTED_MODULE_4__.checkStatusFor)(isOnline, extension.online, extension.offline)) {\n continue;\n }\n extensions.push({\n id,\n name,\n moduleName: extension.moduleName,\n config: extensionConfig,\n featureFlag: extension.featureFlag,\n meta: extension.meta,\n online: extensionConfig?.['Display conditions']?.online ?? extension.online ?? true,\n offline: extensionConfig?.['Display conditions']?.offline ?? extension.offline ?? false\n });\n }\n }\n return extensions;\n}\n/**\n * Gets the list of extensions assigned to a given slot\n *\n * @param slotName The slot to load the assigned extensions for\n * @returns An array of extensions assigned to the named slot\n */ function getAssignedExtensions(slotName) {\n const internalState = extensionInternalStore.getState();\n const { config: slotConfig } = (0,_openmrs_esm_config__WEBPACK_IMPORTED_MODULE_1__.getExtensionSlotConfig)(slotName);\n const extensionStoreState = extensionsConfigStore.getState();\n const featureFlagState = _openmrs_esm_feature_flags__WEBPACK_IMPORTED_MODULE_2__.featureFlagsStore.getState();\n const sessionState = _openmrs_esm_api__WEBPACK_IMPORTED_MODULE_0__.sessionStore.getState();\n const isOnline = (0,_openmrs_esm_utils__WEBPACK_IMPORTED_MODULE_6__.isOnline)();\n const enabledFeatureFlags = Object.entries(featureFlagState.flags).filter(([, { enabled }])=>enabled).map(([name])=>name);\n return getAssignedExtensionsFromSlotData(slotName, internalState, slotConfig, extensionStoreState, enabledFeatureFlags, isOnline, sessionState.session);\n}\nfunction calculateAssignedIds(config, attachedIds) {\n const addedIds = config.add || [];\n const removedIds = config.remove || [];\n const idOrder = config.order || [];\n const { extensions } = extensionInternalStore.getState();\n return [\n ...attachedIds,\n ...addedIds\n ].filter((id)=>!removedIds.includes(id)).sort((idA, idB)=>{\n const ai = getOrder(idA, idOrder, extensions[getExtensionNameFromId(idA)]?.order, attachedIds);\n const bi = getOrder(idB, idOrder, extensions[getExtensionNameFromId(idB)]?.order, attachedIds);\n if (bi === -1) {\n return -1;\n } else if (ai === -1) {\n return 1;\n } else {\n return ai - bi;\n }\n });\n}\n/**\n * Used by by extension slots at mount time.\n *\n * @param moduleName The name of the module that contains the extension slot\n * @param slotName The extension slot name that is actually used\n * @param state Optional custom state for the slot, which will be stored in the extension store.\n * @internal\n */ const registerExtensionSlot = (moduleName, slotName, state)=>extensionInternalStore.setState((currentState)=>{\n const existingModuleName = currentState.slots[slotName]?.moduleName;\n if (existingModuleName && existingModuleName != moduleName) {\n console.warn(`An extension slot with the name '${slotName}' already exists. Refusing to register the same slot name twice (in \"registerExtensionSlot\"). The existing one is from module ${existingModuleName}.`);\n return currentState;\n }\n if (existingModuleName && existingModuleName == moduleName) {\n // Re-rendering an existing slot\n return currentState;\n }\n if (currentState.slots[slotName]) {\n return {\n ...currentState,\n slots: {\n ...currentState.slots,\n [slotName]: {\n ...currentState.slots[slotName],\n moduleName,\n state\n }\n }\n };\n }\n const slot = createNewExtensionSlotInfo(slotName, moduleName, state);\n return {\n ...currentState,\n slots: {\n ...currentState.slots,\n [slotName]: {\n ...slot\n }\n }\n };\n });\n/**\n * Used by extension slots to update the copy of the state for the extension slot\n *\n * @param slotName The name of the slot with state to update\n * @param state A copy of the new state\n * @param partial Whether this should be applied as a partial\n */ function updateExtensionSlotState(slotName, state, partial = false) {\n extensionInternalStore.setState((currentState)=>{\n const newState = partial ? (0,lodash_es__WEBPACK_IMPORTED_MODULE_8__[\"default\"])(currentState.slots[slotName].state, state) : state;\n return {\n ...currentState,\n slots: {\n ...currentState.slots,\n [slotName]: {\n ...currentState.slots[slotName],\n state: newState\n }\n }\n };\n });\n}\n/**\n * @internal\n * Just for testing.\n */ const reset = ()=>extensionStore.setState(()=>{\n return {\n slots: {},\n extensions: {}\n };\n });\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi4vLi4vZnJhbWV3b3JrL2VzbS1leHRlbnNpb25zL2Rpc3QvZXh0ZW5zaW9ucy5qcyIsIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSxnQ0FBZ0MsR0FBRzs7Ozs7OztDQU9sQyxHQUFrRTtBQUMwSjtBQUN2SjtBQUNQO0FBQ0s7QUFDUjtBQUNqQjtBQUNHO0FBQzBEO0FBQ3hHLE1BQU1tQix5QkFBeUJILG9FQUF5QkE7QUFDeEQsTUFBTUksaUJBQWlCSCw0REFBaUJBO0FBQ3hDLE1BQU1JLG1CQUFtQmYsaUZBQTRCQTtBQUNyRCxNQUFNZ0Isd0JBQXdCZiw2RUFBd0JBO0FBQ3RELGdDQUFnQztBQUNoQyxTQUFTZ0IsMkJBQTJCQyxhQUFhLEVBQUVDLG9CQUFvQixFQUFFSCxxQkFBcUIsRUFBRUksZ0JBQWdCLEVBQUUxQixZQUFZO0lBQzFILE1BQU0yQixRQUFRLENBQUM7SUFDZixNQUFNaEIsV0FBV0MsNERBQVVBO0lBQzNCLE1BQU1nQixzQkFBc0JDLE9BQU9DLE9BQU8sQ0FBQ0osaUJBQWlCSyxLQUFLLEVBQUVDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsRUFBRUMsT0FBTyxFQUFFLENBQUMsR0FBR0EsU0FBU0MsR0FBRyxDQUFDLENBQUMsQ0FBQ0MsS0FBSyxHQUFHQTtJQUNwSCxLQUFLLElBQUksQ0FBQ0MsVUFBVUMsS0FBSyxJQUFJUixPQUFPQyxPQUFPLENBQUNOLGNBQWNHLEtBQUssRUFBRTtRQUM3RCxNQUFNLEVBQUVXLE1BQU0sRUFBRSxHQUFHakMsb0ZBQStCQSxDQUFDb0Isc0JBQXNCWSxLQUFLRixJQUFJO1FBQ2xGLE1BQU1JLHFCQUFxQkMsa0NBQWtDSixVQUFVWixlQUFlYyxRQUFRaEIsdUJBQXVCTSxxQkFBcUJqQixVQUFVWCxhQUFheUMsT0FBTztRQUN4S2QsS0FBSyxDQUFDUyxTQUFTLEdBQUc7WUFDZE0sWUFBWUwsS0FBS0ssVUFBVTtZQUMzQkg7UUFDSjtJQUNKO0lBQ0EsSUFBSSxDQUFDMUIscURBQU9BLENBQUNPLGVBQWV1QixRQUFRLEdBQUdoQixLQUFLLEVBQUVBLFFBQVE7UUFDbERQLGVBQWV3QixRQUFRLENBQUM7WUFDcEJqQjtRQUNKO0lBQ0o7QUFDSjtBQUNBUix1QkFBdUIwQixTQUFTLENBQUMsQ0FBQ0M7SUFDOUJ2QiwyQkFBMkJ1QixlQUFlekIsaUJBQWlCc0IsUUFBUSxJQUFJckIsc0JBQXNCcUIsUUFBUSxJQUFJbEMseUVBQWlCQSxDQUFDa0MsUUFBUSxJQUFJM0MsMERBQVlBLENBQUMyQyxRQUFRO0FBQ2hLO0FBQ0F0QixpQkFBaUJ3QixTQUFTLENBQUMsQ0FBQ0U7SUFDeEJ4QiwyQkFBMkJKLHVCQUF1QndCLFFBQVEsSUFBSUksYUFBYXpCLHNCQUFzQnFCLFFBQVEsSUFBSWxDLHlFQUFpQkEsQ0FBQ2tDLFFBQVEsSUFBSTNDLDBEQUFZQSxDQUFDMkMsUUFBUTtBQUNwSztBQUNBckIsc0JBQXNCdUIsU0FBUyxDQUFDLENBQUNHO0lBQzdCekIsMkJBQTJCSix1QkFBdUJ3QixRQUFRLElBQUl0QixpQkFBaUJzQixRQUFRLElBQUlLLGtCQUFrQnZDLHlFQUFpQkEsQ0FBQ2tDLFFBQVEsSUFBSTNDLDBEQUFZQSxDQUFDMkMsUUFBUTtBQUNwSztBQUNBbEMseUVBQWlCQSxDQUFDb0MsU0FBUyxDQUFDLENBQUNuQjtJQUN6QkgsMkJBQTJCSix1QkFBdUJ3QixRQUFRLElBQUl0QixpQkFBaUJzQixRQUFRLElBQUlyQixzQkFBc0JxQixRQUFRLElBQUlqQixrQkFBa0IxQiwwREFBWUEsQ0FBQzJDLFFBQVE7QUFDeEs7QUFDQTNDLDBEQUFZQSxDQUFDNkMsU0FBUyxDQUFDLENBQUNKO0lBQ3BCbEIsMkJBQTJCSix1QkFBdUJ3QixRQUFRLElBQUl0QixpQkFBaUJzQixRQUFRLElBQUlyQixzQkFBc0JxQixRQUFRLElBQUlsQyx5RUFBaUJBLENBQUNrQyxRQUFRLElBQUlGO0FBQy9KO0FBQ0EsU0FBU1E7SUFDTDFCLDJCQUEyQkosdUJBQXVCd0IsUUFBUSxJQUFJdEIsaUJBQWlCc0IsUUFBUSxJQUFJckIsc0JBQXNCcUIsUUFBUSxJQUFJbEMseUVBQWlCQSxDQUFDa0MsUUFBUSxJQUFJM0MsMERBQVlBLENBQUMyQyxRQUFRO0FBQ3BMO0FBQ0FNO0FBQ0F2QyxrRkFBNEJBLENBQUN1QztBQUM3QixTQUFTQywyQkFBMkJkLFFBQVEsRUFBRU0sVUFBVSxFQUFFUyxLQUFLO0lBQzNELE9BQU87UUFDSFQ7UUFDQVAsTUFBTUM7UUFDTmdCLGFBQWEsRUFBRTtRQUNmZCxRQUFRO1FBQ1JhO0lBQ0o7QUFDSjtBQUNBOzs7Ozs7Ozs7Ozs7Q0FZQyxHQUFVLFNBQVNFLHVCQUF1QkMsV0FBVztJQUNsRCxNQUFNLENBQUNDLGNBQWMsR0FBR0QsWUFBWUUsS0FBSyxDQUFDO0lBQzFDLE9BQU9EO0FBQ1g7QUFDTyxTQUFTRSw2QkFBNkJOLEtBQUssRUFBRUcsV0FBVztJQUMzRCxNQUFNbkIsT0FBT2tCLHVCQUF1QkM7SUFDcEMsT0FBT0gsTUFBTU8sVUFBVSxDQUFDdkIsS0FBSztBQUNqQztBQUNPLFNBQVN3Qix5QkFBeUJMLFdBQVc7SUFDaEQsTUFBTUgsUUFBUWhDLHVCQUF1QndCLFFBQVE7SUFDN0MsT0FBT2MsNkJBQTZCTixPQUFPRztBQUMvQztBQUNBOzs7OztDQUtDLEdBQVUsTUFBTU0sb0JBQW9CLENBQUNDLHdCQUF3QjFDLHVCQUF1QnlCLFFBQVEsQ0FBQyxDQUFDTztRQUN2RkEsTUFBTU8sVUFBVSxDQUFDRyxzQkFBc0IxQixJQUFJLENBQUMsR0FBRztZQUMzQyxHQUFHMEIscUJBQXFCO1lBQ3hCQyxXQUFXLEVBQUU7UUFDakI7UUFDQSxPQUFPWDtJQUNYLEdBQUc7QUFDUDs7Ozs7Ozs7Ozs7Ozs7Ozs7O0NBa0JDLEdBQVUsU0FBU1ksT0FBTzNCLFFBQVEsRUFBRWtCLFdBQVc7SUFDNUNwQyx1RUFBNEJBLENBQUMsQ0FBQ2lDO1FBQzFCLE1BQU1hLGVBQWViLE1BQU14QixLQUFLLENBQUNTLFNBQVM7UUFDMUMsSUFBSSxDQUFDNEIsY0FBYztZQUNmLE9BQU87Z0JBQ0gsR0FBR2IsS0FBSztnQkFDUnhCLE9BQU87b0JBQ0gsR0FBR3dCLE1BQU14QixLQUFLO29CQUNkLENBQUNTLFNBQVMsRUFBRTt3QkFDUixHQUFHYywyQkFBMkJkLFNBQVM7d0JBQ3ZDZ0IsYUFBYTs0QkFDVEU7eUJBQ0g7b0JBQ0w7Z0JBQ0o7WUFDSjtRQUNKLE9BQU87WUFDSCxPQUFPO2dCQUNILEdBQUdILEtBQUs7Z0JBQ1J4QixPQUFPO29CQUNILEdBQUd3QixNQUFNeEIsS0FBSztvQkFDZCxDQUFDUyxTQUFTLEVBQUU7d0JBQ1IsR0FBRzRCLFlBQVk7d0JBQ2ZaLGFBQWE7K0JBQ05ZLGFBQWFaLFdBQVc7NEJBQzNCRTt5QkFDSDtvQkFDTDtnQkFDSjtZQUNKO1FBQ0o7SUFDSjtBQUNKO0FBQ0E7O0NBRUMsR0FBVSxTQUFTVyxPQUFPQyxpQkFBaUIsRUFBRVosV0FBVztJQUNyRHBDLHVFQUE0QkEsQ0FBQyxDQUFDaUM7UUFDMUIsTUFBTWEsZUFBZWIsTUFBTXhCLEtBQUssQ0FBQ3VDLGtCQUFrQjtRQUNuRCxJQUFJRixnQkFBZ0JBLGFBQWFaLFdBQVcsQ0FBQ2UsUUFBUSxDQUFDYixjQUFjO1lBQ2hFLE9BQU87Z0JBQ0gsR0FBR0gsS0FBSztnQkFDUnhCLE9BQU87b0JBQ0gsR0FBR3dCLE1BQU14QixLQUFLO29CQUNkLENBQUN1QyxrQkFBa0IsRUFBRTt3QkFDakIsR0FBR0YsWUFBWTt3QkFDZlosYUFBYVksYUFBYVosV0FBVyxDQUFDcEIsTUFBTSxDQUFDLENBQUNvQyxLQUFLQSxPQUFPZDtvQkFDOUQ7Z0JBQ0o7WUFDSjtRQUNKLE9BQU87WUFDSCxPQUFPSDtRQUNYO0lBQ0o7QUFDSjtBQUNBOztDQUVDLEdBQVUsU0FBU2tCLFVBQVVILGlCQUFpQjtJQUMzQ2hELHVFQUE0QkEsQ0FBQyxDQUFDaUM7UUFDMUIsTUFBTWEsZUFBZWIsTUFBTXhCLEtBQUssQ0FBQ3VDLGtCQUFrQjtRQUNuRCxJQUFJRixjQUFjO1lBQ2QsT0FBTztnQkFDSCxHQUFHYixLQUFLO2dCQUNSeEIsT0FBTztvQkFDSCxHQUFHd0IsTUFBTXhCLEtBQUs7b0JBQ2QsQ0FBQ3VDLGtCQUFrQixFQUFFO3dCQUNqQixHQUFHRixZQUFZO3dCQUNmWixhQUFhLEVBQUU7b0JBQ25CO2dCQUNKO1lBQ0o7UUFDSixPQUFPO1lBQ0gsT0FBT0Q7UUFDWDtJQUNKO0FBQ0o7QUFDQTs7OztDQUlDLEdBQUcsU0FBU21CLFNBQVNoQixXQUFXLEVBQUVpQixlQUFlLEVBQUVDLG9CQUFvQixFQUFFQyxhQUFhO0lBQ25GLE1BQU1DLGtCQUFrQkgsZ0JBQWdCSSxPQUFPLENBQUNyQjtJQUNoRCxJQUFJb0Isb0JBQW9CLENBQUMsR0FBRztRQUN4QixPQUFPQTtJQUNYLE9BQU8sSUFBSUYseUJBQXlCSSxXQUFXO1FBQzNDLGtGQUFrRjtRQUNsRixPQUFPLE9BQU9KO0lBQ2xCLE9BQU87UUFDSCxNQUFNSyxnQkFBZ0JKLGNBQWNFLE9BQU8sQ0FBQ3JCO1FBQzVDLElBQUl1QixrQkFBa0IsQ0FBQyxHQUFHO1lBQ3RCLCtFQUErRTtZQUMvRSxtQkFBbUI7WUFDbkIsT0FBTyxPQUFPQTtRQUNsQixPQUFPO1lBQ0gsT0FBTyxDQUFDO1FBQ1o7SUFDSjtBQUNKO0FBQ0EsU0FBU3JDLGtDQUFrQ0osUUFBUSxFQUFFWixhQUFhLEVBQUVjLE1BQU0sRUFBRXdDLHlCQUF5QixFQUFFbEQsbUJBQW1CLEVBQUVqQixRQUFRLEVBQUU4QixPQUFPO0lBQ3pJLE1BQU1XLGNBQWM1QixjQUFjRyxLQUFLLENBQUNTLFNBQVMsQ0FBQ2dCLFdBQVc7SUFDN0QsTUFBTTJCLGNBQWNDLHFCQUFxQjFDLFFBQVFjO0lBQ2pELE1BQU1NLGFBQWEsRUFBRTtJQUNyQixzREFBc0Q7SUFDdEQsTUFBTXVCLFlBQVl6RCxjQUFjRyxLQUFLLENBQUNTLFNBQVMsRUFBRWU7SUFDakQsTUFBTStCLG9CQUFvQkQsYUFBYSxPQUFPQSxjQUFjLFdBQVc7UUFDbkV4QztRQUNBLEdBQUd3QyxTQUFTO0lBQ2hCLElBQUk7UUFDQXhDO0lBQ0o7SUFDQSxLQUFLLElBQUkyQixNQUFNVyxZQUFZO1FBQ3ZCLE1BQU0sRUFBRXpDLFFBQVE2QyxrQkFBa0IsRUFBRSxHQUFHaEYsZ0ZBQTJCQSxDQUFDMkUsMkJBQTJCMUMsVUFBVWdDO1FBQ3hHLE1BQU1nQixrQ0FBa0NsRiw2RkFBd0NBLENBQUNvQyxRQUFRRixVQUFVZ0M7UUFDbkcsTUFBTWlCLGtCQUFrQnZFLHFEQUFLQSxDQUFDcUUsb0JBQW9CQztRQUNsRCxNQUFNakQsT0FBT2tCLHVCQUF1QmU7UUFDcEMsTUFBTWtCLFlBQVk5RCxjQUFja0MsVUFBVSxDQUFDdkIsS0FBSztRQUNoRCxrRUFBa0U7UUFDbEUsSUFBSW1ELFdBQVc7WUFDWCxNQUFNQyxxQkFBcUJGLGlCQUFpQixDQUFDLHFCQUFxQixFQUFFRyxjQUFjRixVQUFVRSxVQUFVLElBQUksRUFBRTtZQUM1RyxJQUFJRCxzQkFBdUIsUUFBT0EsdUJBQXVCLFlBQVlFLE1BQU1DLE9BQU8sQ0FBQ0gsdUJBQXVCQSxtQkFBbUJJLE1BQU0sR0FBRyxJQUFJO2dCQUN0SSxJQUFJLENBQUNsRCxTQUFTbUQsTUFBTTtvQkFDaEI7Z0JBQ0o7Z0JBQ0EsSUFBSSxDQUFDM0YsK0RBQWFBLENBQUNzRixvQkFBb0I5QyxRQUFRbUQsSUFBSSxHQUFHO29CQUNsRDtnQkFDSjtZQUNKO1lBQ0EsTUFBTUMsNkJBQTZCUixpQkFBaUIsQ0FBQyxxQkFBcUIsRUFBRVMsY0FBY1IsVUFBVVMsaUJBQWlCO1lBQ3JILElBQUlGLCtCQUErQmpCLGFBQWEsT0FBT2lCLCtCQUErQixZQUFZQSwyQkFBMkJHLElBQUksR0FBR0wsTUFBTSxHQUFHLEdBQUc7Z0JBQzVJLElBQUk7b0JBQ0EsSUFBSSxDQUFDbkYsb0ZBQWlCQSxDQUFDcUYsNEJBQTRCWCxvQkFBb0I7d0JBQ25FO29CQUNKO2dCQUNKLEVBQUUsT0FBT2UsR0FBRztvQkFDUkMsUUFBUUMsS0FBSyxDQUFDLENBQUMsbUNBQW1DLEVBQUVOLDJCQUEyQixnQkFBZ0IsRUFBRTFELEtBQUssU0FBUyxFQUFFQyxVQUFVLEVBQUU2RDtvQkFDN0g7Z0JBQ0o7WUFDSjtZQUNBLElBQUlYLFVBQVVjLFdBQVcsSUFBSSxDQUFDeEUsb0JBQW9CdUMsUUFBUSxDQUFDbUIsVUFBVWMsV0FBVyxHQUFHO2dCQUMvRTtZQUNKO1lBQ0EsSUFBSUMsT0FBT0MsY0FBYyxJQUFJLENBQUN2RiwyREFBY0EsQ0FBQ0osVUFBVTJFLFVBQVVpQixNQUFNLEVBQUVqQixVQUFVa0IsT0FBTyxHQUFHO2dCQUN6RjtZQUNKO1lBQ0E5QyxXQUFXK0MsSUFBSSxDQUFDO2dCQUNackM7Z0JBQ0FqQztnQkFDQU8sWUFBWTRDLFVBQVU1QyxVQUFVO2dCQUNoQ0osUUFBUStDO2dCQUNSZSxhQUFhZCxVQUFVYyxXQUFXO2dCQUNsQ00sTUFBTXBCLFVBQVVvQixJQUFJO2dCQUNwQkgsUUFBUWxCLGlCQUFpQixDQUFDLHFCQUFxQixFQUFFa0IsVUFBVWpCLFVBQVVpQixNQUFNLElBQUk7Z0JBQy9FQyxTQUFTbkIsaUJBQWlCLENBQUMscUJBQXFCLEVBQUVtQixXQUFXbEIsVUFBVWtCLE9BQU8sSUFBSTtZQUN0RjtRQUNKO0lBQ0o7SUFDQSxPQUFPOUM7QUFDWDtBQUNBOzs7OztDQUtDLEdBQVUsU0FBU2lELHNCQUFzQnZFLFFBQVE7SUFDOUMsTUFBTVosZ0JBQWdCTCx1QkFBdUJ3QixRQUFRO0lBQ3JELE1BQU0sRUFBRUwsUUFBUXNFLFVBQVUsRUFBRSxHQUFHeEcsMkVBQXNCQSxDQUFDZ0M7SUFDdEQsTUFBTXlFLHNCQUFzQnZGLHNCQUFzQnFCLFFBQVE7SUFDMUQsTUFBTW1FLG1CQUFtQnJHLHlFQUFpQkEsQ0FBQ2tDLFFBQVE7SUFDbkQsTUFBTW9FLGVBQWUvRywwREFBWUEsQ0FBQzJDLFFBQVE7SUFDMUMsTUFBTWhDLFdBQVdDLDREQUFVQTtJQUMzQixNQUFNZ0Isc0JBQXNCQyxPQUFPQyxPQUFPLENBQUNnRixpQkFBaUIvRSxLQUFLLEVBQUVDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsRUFBRUMsT0FBTyxFQUFFLENBQUMsR0FBR0EsU0FBU0MsR0FBRyxDQUFDLENBQUMsQ0FBQ0MsS0FBSyxHQUFHQTtJQUNwSCxPQUFPSyxrQ0FBa0NKLFVBQVVaLGVBQWVvRixZQUFZQyxxQkFBcUJqRixxQkFBcUJqQixVQUFVb0csYUFBYXRFLE9BQU87QUFDMUo7QUFDQSxTQUFTdUMscUJBQXFCMUMsTUFBTSxFQUFFYyxXQUFXO0lBQzdDLE1BQU00RCxXQUFXMUUsT0FBTzJFLEdBQUcsSUFBSSxFQUFFO0lBQ2pDLE1BQU1DLGFBQWE1RSxPQUFPNkUsTUFBTSxJQUFJLEVBQUU7SUFDdEMsTUFBTUMsVUFBVTlFLE9BQU8rRSxLQUFLLElBQUksRUFBRTtJQUNsQyxNQUFNLEVBQUUzRCxVQUFVLEVBQUUsR0FBR3ZDLHVCQUF1QndCLFFBQVE7SUFDdEQsT0FBTztXQUNBUztXQUNBNEQ7S0FDTixDQUFDaEYsTUFBTSxDQUFDLENBQUNvQyxLQUFLLENBQUM4QyxXQUFXL0MsUUFBUSxDQUFDQyxLQUFLa0QsSUFBSSxDQUFDLENBQUNDLEtBQUtDO1FBQ2hELE1BQU1DLEtBQUtuRCxTQUFTaUQsS0FBS0gsU0FBUzFELFVBQVUsQ0FBQ0wsdUJBQXVCa0UsS0FBSyxFQUFFRixPQUFPakU7UUFDbEYsTUFBTXNFLEtBQUtwRCxTQUFTa0QsS0FBS0osU0FBUzFELFVBQVUsQ0FBQ0wsdUJBQXVCbUUsS0FBSyxFQUFFSCxPQUFPakU7UUFDbEYsSUFBSXNFLE9BQU8sQ0FBQyxHQUFHO1lBQ1gsT0FBTyxDQUFDO1FBQ1osT0FBTyxJQUFJRCxPQUFPLENBQUMsR0FBRztZQUNsQixPQUFPO1FBQ1gsT0FBTztZQUNILE9BQU9BLEtBQUtDO1FBQ2hCO0lBQ0o7QUFDSjtBQUNBOzs7Ozs7O0NBT0MsR0FBVSxNQUFNQyx3QkFBd0IsQ0FBQ2pGLFlBQVlOLFVBQVVlLFFBQVFoQyx1QkFBdUJ5QixRQUFRLENBQUMsQ0FBQ2dGO1FBQ2pHLE1BQU1DLHFCQUFxQkQsYUFBYWpHLEtBQUssQ0FBQ1MsU0FBUyxFQUFFTTtRQUN6RCxJQUFJbUYsc0JBQXNCQSxzQkFBc0JuRixZQUFZO1lBQ3hEd0QsUUFBUTRCLElBQUksQ0FBQyxDQUFDLGlDQUFpQyxFQUFFMUYsU0FBUyw4SEFBOEgsRUFBRXlGLG1CQUFtQixDQUFDLENBQUM7WUFDL00sT0FBT0Q7UUFDWDtRQUNBLElBQUlDLHNCQUFzQkEsc0JBQXNCbkYsWUFBWTtZQUN4RCxnQ0FBZ0M7WUFDaEMsT0FBT2tGO1FBQ1g7UUFDQSxJQUFJQSxhQUFhakcsS0FBSyxDQUFDUyxTQUFTLEVBQUU7WUFDOUIsT0FBTztnQkFDSCxHQUFHd0YsWUFBWTtnQkFDZmpHLE9BQU87b0JBQ0gsR0FBR2lHLGFBQWFqRyxLQUFLO29CQUNyQixDQUFDUyxTQUFTLEVBQUU7d0JBQ1IsR0FBR3dGLGFBQWFqRyxLQUFLLENBQUNTLFNBQVM7d0JBQy9CTTt3QkFDQVM7b0JBQ0o7Z0JBQ0o7WUFDSjtRQUNKO1FBQ0EsTUFBTWQsT0FBT2EsMkJBQTJCZCxVQUFVTSxZQUFZUztRQUM5RCxPQUFPO1lBQ0gsR0FBR3lFLFlBQVk7WUFDZmpHLE9BQU87Z0JBQ0gsR0FBR2lHLGFBQWFqRyxLQUFLO2dCQUNyQixDQUFDUyxTQUFTLEVBQUU7b0JBQ1IsR0FBR0MsSUFBSTtnQkFDWDtZQUNKO1FBQ0o7SUFDSixHQUFHO0FBQ1A7Ozs7OztDQU1DLEdBQVUsU0FBUzBGLHlCQUF5QjNGLFFBQVEsRUFBRWUsS0FBSyxFQUFFNkUsVUFBVSxLQUFLO0lBQ3pFN0csdUJBQXVCeUIsUUFBUSxDQUFDLENBQUNnRjtRQUM3QixNQUFNSyxXQUFXRCxVQUFVbEgscURBQUtBLENBQUM4RyxhQUFhakcsS0FBSyxDQUFDUyxTQUFTLENBQUNlLEtBQUssRUFBRUEsU0FBU0E7UUFDOUUsT0FBTztZQUNILEdBQUd5RSxZQUFZO1lBQ2ZqRyxPQUFPO2dCQUNILEdBQUdpRyxhQUFhakcsS0FBSztnQkFDckIsQ0FBQ1MsU0FBUyxFQUFFO29CQUNSLEdBQUd3RixhQUFhakcsS0FBSyxDQUFDUyxTQUFTO29CQUMvQmUsT0FBTzhFO2dCQUNYO1lBQ0o7UUFDSjtJQUNKO0FBQ0o7QUFDQTs7O0NBR0MsR0FBVSxNQUFNQyxRQUFRLElBQUk5RyxlQUFld0IsUUFBUSxDQUFDO1FBQzdDLE9BQU87WUFDSGpCLE9BQU8sQ0FBQztZQUNSK0IsWUFBWSxDQUFDO1FBQ2pCO0lBQ0osR0FBRyIsInNvdXJjZXMiOlsid2VicGFjazovL0BvcGVubXJzL2VzbS1hcHAtc2hlbGwvLi4vLi4vZnJhbWV3b3JrL2VzbS1leHRlbnNpb25zL2Rpc3QvZXh0ZW5zaW9ucy5qcz9jMGU3Il0sInNvdXJjZXNDb250ZW50IjpbIi8qKiBAbW9kdWxlIEBjYXRlZ29yeSBFeHRlbnNpb24gKi8gLypcbiAqIFdlIGhhdmUgdGhlIGZvbGxvd2luZyBleHRlbnNpb24gbW9kZXM6XG4gKlxuICogLSBhdHRhY2hlZCAoc2V0IHZpYSBjb2RlIGluIGZvcm0gb2Y6IGF0dGFjaCwgZGV0YWNoLCAuLi4pXG4gKiAtIGNvbmZpZ3VyZWQgKHNldCB2aWEgY29uZmlndXJhdGlvbiBpbiBmb3JtIG9mOiBhZGRlZCwgcmVtb3ZlZCwgLi4uKVxuICogLSBhc3NpZ25lZCAoY29tcHV0ZWQgZnJvbSBhdHRhY2hlZCBhbmQgY29uZmlndXJlZClcbiAqIC0gY29ubmVjdGVkIChjb21wdXRlZCBmcm9tIGFzc2lnbmVkIHVzaW5nIGNvbm5lY3Rpdml0eSBhbmQgb25saW5lIC8gb2ZmbGluZSlcbiAqLyBpbXBvcnQgeyBzZXNzaW9uU3RvcmUsIHVzZXJIYXNBY2Nlc3MgfSBmcm9tIFwiQG9wZW5tcnMvZXNtLWFwaVwiO1xuaW1wb3J0IHsgZ2V0RXh0ZW5zaW9uQ29uZmlnRnJvbUV4dGVuc2lvblNsb3RTdG9yZSwgZ2V0RXh0ZW5zaW9uQ29uZmlnRnJvbVN0b3JlLCBnZXRFeHRlbnNpb25TbG90Q29uZmlnLCBnZXRFeHRlbnNpb25TbG90Q29uZmlnRnJvbVN0b3JlLCBnZXRFeHRlbnNpb25TbG90c0NvbmZpZ1N0b3JlLCBnZXRFeHRlbnNpb25zQ29uZmlnU3RvcmUgfSBmcm9tIFwiQG9wZW5tcnMvZXNtLWNvbmZpZ1wiO1xuaW1wb3J0IHsgZXZhbHVhdGVBc0Jvb2xlYW4gfSBmcm9tIFwiQG9wZW5tcnMvZXNtLWV4cHJlc3Npb24tZXZhbHVhdG9yXCI7XG5pbXBvcnQgeyBmZWF0dXJlRmxhZ3NTdG9yZSB9IGZyb20gXCJAb3Blbm1ycy9lc20tZmVhdHVyZS1mbGFnc1wiO1xuaW1wb3J0IHsgc3Vic2NyaWJlQ29ubmVjdGl2aXR5Q2hhbmdlZCB9IGZyb20gXCJAb3Blbm1ycy9lc20tZ2xvYmFsc1wiO1xuaW1wb3J0IHsgaXNPbmxpbmUgYXMgaXNPbmxpbmVGbiB9IGZyb20gXCJAb3Blbm1ycy9lc20tdXRpbHNcIjtcbmltcG9ydCB7IGlzRXF1YWwsIG1lcmdlIH0gZnJvbSBcImxvZGFzaC1lc1wiO1xuaW1wb3J0IHsgY2hlY2tTdGF0dXNGb3IgfSBmcm9tIFwiLi9oZWxwZXJzLmpzXCI7XG5pbXBvcnQgeyBnZXRFeHRlbnNpb25JbnRlcm5hbFN0b3JlLCBnZXRFeHRlbnNpb25TdG9yZSwgdXBkYXRlSW50ZXJuYWxFeHRlbnNpb25TdG9yZSB9IGZyb20gXCIuL3N0b3JlLmpzXCI7XG5jb25zdCBleHRlbnNpb25JbnRlcm5hbFN0b3JlID0gZ2V0RXh0ZW5zaW9uSW50ZXJuYWxTdG9yZSgpO1xuY29uc3QgZXh0ZW5zaW9uU3RvcmUgPSBnZXRFeHRlbnNpb25TdG9yZSgpO1xuY29uc3Qgc2xvdHNDb25maWdTdG9yZSA9IGdldEV4dGVuc2lvblNsb3RzQ29uZmlnU3RvcmUoKTtcbmNvbnN0IGV4dGVuc2lvbnNDb25maWdTdG9yZSA9IGdldEV4dGVuc2lvbnNDb25maWdTdG9yZSgpO1xuLy8gS2VlcCB0aGUgb3V0cHV0IHN0b3JlIHVwZGF0ZWRcbmZ1bmN0aW9uIHVwZGF0ZUV4dGVuc2lvbk91dHB1dFN0b3JlKGludGVybmFsU3RhdGUsIGV4dGVuc2lvblNsb3RDb25maWdzLCBleHRlbnNpb25zQ29uZmlnU3RvcmUsIGZlYXR1cmVGbGFnU3RvcmUsIHNlc3Npb25TdG9yZSkge1xuICAgIGNvbnN0IHNsb3RzID0ge307XG4gICAgY29uc3QgaXNPbmxpbmUgPSBpc09ubGluZUZuKCk7XG4gICAgY29uc3QgZW5hYmxlZEZlYXR1cmVGbGFncyA9IE9iamVjdC5lbnRyaWVzKGZlYXR1cmVGbGFnU3RvcmUuZmxhZ3MpLmZpbHRlcigoWywgeyBlbmFibGVkIH1dKT0+ZW5hYmxlZCkubWFwKChbbmFtZV0pPT5uYW1lKTtcbiAgICBmb3IgKGxldCBbc2xvdE5hbWUsIHNsb3RdIG9mIE9iamVjdC5lbnRyaWVzKGludGVybmFsU3RhdGUuc2xvdHMpKXtcbiAgICAgICAgY29uc3QgeyBjb25maWcgfSA9IGdldEV4dGVuc2lvblNsb3RDb25maWdGcm9tU3RvcmUoZXh0ZW5zaW9uU2xvdENvbmZpZ3MsIHNsb3QubmFtZSk7XG4gICAgICAgIGNvbnN0IGFzc2lnbmVkRXh0ZW5zaW9ucyA9IGdldEFzc2lnbmVkRXh0ZW5zaW9uc0Zyb21TbG90RGF0YShzbG90TmFtZSwgaW50ZXJuYWxTdGF0ZSwgY29uZmlnLCBleHRlbnNpb25zQ29uZmlnU3RvcmUsIGVuYWJsZWRGZWF0dXJlRmxhZ3MsIGlzT25saW5lLCBzZXNzaW9uU3RvcmUuc2Vzc2lvbik7XG4gICAgICAgIHNsb3RzW3Nsb3ROYW1lXSA9IHtcbiAgICAgICAgICAgIG1vZHVsZU5hbWU6IHNsb3QubW9kdWxlTmFtZSxcbiAgICAgICAgICAgIGFzc2lnbmVkRXh0ZW5zaW9uc1xuICAgICAgICB9O1xuICAgIH1cbiAgICBpZiAoIWlzRXF1YWwoZXh0ZW5zaW9uU3RvcmUuZ2V0U3RhdGUoKS5zbG90cywgc2xvdHMpKSB7XG4gICAgICAgIGV4dGVuc2lvblN0b3JlLnNldFN0YXRlKHtcbiAgICAgICAgICAgIHNsb3RzXG4gICAgICAgIH0pO1xuICAgIH1cbn1cbmV4dGVuc2lvbkludGVybmFsU3RvcmUuc3Vic2NyaWJlKChpbnRlcm5hbFN0b3JlKT0+e1xuICAgIHVwZGF0ZUV4dGVuc2lvbk91dHB1dFN0b3JlKGludGVybmFsU3RvcmUsIHNsb3RzQ29uZmlnU3RvcmUuZ2V0U3RhdGUoKSwgZXh0ZW5zaW9uc0NvbmZpZ1N0b3JlLmdldFN0YXRlKCksIGZlYXR1cmVGbGFnc1N0b3JlLmdldFN0YXRlKCksIHNlc3Npb25TdG9yZS5nZXRTdGF0ZSgpKTtcbn0pO1xuc2xvdHNDb25maWdTdG9yZS5zdWJzY3JpYmUoKHNsb3RDb25maWdzKT0+e1xuICAgIHVwZGF0ZUV4dGVuc2lvbk91dHB1dFN0b3JlKGV4dGVuc2lvbkludGVybmFsU3RvcmUuZ2V0U3RhdGUoKSwgc2xvdENvbmZpZ3MsIGV4dGVuc2lvbnNDb25maWdTdG9yZS5nZXRTdGF0ZSgpLCBmZWF0dXJlRmxhZ3NTdG9yZS5nZXRTdGF0ZSgpLCBzZXNzaW9uU3RvcmUuZ2V0U3RhdGUoKSk7XG59KTtcbmV4dGVuc2lvbnNDb25maWdTdG9yZS5zdWJzY3JpYmUoKGV4dGVuc2lvbkNvbmZpZ3MpPT57XG4gICAgdXBkYXRlRXh0ZW5zaW9uT3V0cHV0U3RvcmUoZXh0ZW5zaW9uSW50ZXJuYWxTdG9yZS5nZXRTdGF0ZSgpLCBzbG90c0NvbmZpZ1N0b3JlLmdldFN0YXRlKCksIGV4dGVuc2lvbkNvbmZpZ3MsIGZlYXR1cmVGbGFnc1N0b3JlLmdldFN0YXRlKCksIHNlc3Npb25TdG9yZS5nZXRTdGF0ZSgpKTtcbn0pO1xuZmVhdHVyZUZsYWdzU3RvcmUuc3Vic2NyaWJlKChmZWF0dXJlRmxhZ1N0b3JlKT0+e1xuICAgIHVwZGF0ZUV4dGVuc2lvbk91dHB1dFN0b3JlKGV4dGVuc2lvbkludGVybmFsU3RvcmUuZ2V0U3RhdGUoKSwgc2xvdHNDb25maWdTdG9yZS5nZXRTdGF0ZSgpLCBleHRlbnNpb25zQ29uZmlnU3RvcmUuZ2V0U3RhdGUoKSwgZmVhdHVyZUZsYWdTdG9yZSwgc2Vzc2lvblN0b3JlLmdldFN0YXRlKCkpO1xufSk7XG5zZXNzaW9uU3RvcmUuc3Vic2NyaWJlKChzZXNzaW9uKT0+e1xuICAgIHVwZGF0ZUV4dGVuc2lvbk91dHB1dFN0b3JlKGV4dGVuc2lvbkludGVybmFsU3RvcmUuZ2V0U3RhdGUoKSwgc2xvdHNDb25maWdTdG9yZS5nZXRTdGF0ZSgpLCBleHRlbnNpb25zQ29uZmlnU3RvcmUuZ2V0U3RhdGUoKSwgZmVhdHVyZUZsYWdzU3RvcmUuZ2V0U3RhdGUoKSwgc2Vzc2lvbik7XG59KTtcbmZ1bmN0aW9uIHVwZGF0ZU91dHB1dFN0b3JlVG9DdXJyZW50KCkge1xuICAgIHVwZGF0ZUV4dGVuc2lvbk91dHB1dFN0b3JlKGV4dGVuc2lvbkludGVybmFsU3RvcmUuZ2V0U3RhdGUoKSwgc2xvdHNDb25maWdTdG9yZS5nZXRTdGF0ZSgpLCBleHRlbnNpb25zQ29uZmlnU3RvcmUuZ2V0U3RhdGUoKSwgZmVhdHVyZUZsYWdzU3RvcmUuZ2V0U3RhdGUoKSwgc2Vzc2lvblN0b3JlLmdldFN0YXRlKCkpO1xufVxudXBkYXRlT3V0cHV0U3RvcmVUb0N1cnJlbnQoKTtcbnN1YnNjcmliZUNvbm5lY3Rpdml0eUNoYW5nZWQodXBkYXRlT3V0cHV0U3RvcmVUb0N1cnJlbnQpO1xuZnVuY3Rpb24gY3JlYXRlTmV3RXh0ZW5zaW9uU2xvdEluZm8oc2xvdE5hbWUsIG1vZHVsZU5hbWUsIHN0YXRlKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgbW9kdWxlTmFtZSxcbiAgICAgICAgbmFtZTogc2xvdE5hbWUsXG4gICAgICAgIGF0dGFjaGVkSWRzOiBbXSxcbiAgICAgICAgY29uZmlnOiBudWxsLFxuICAgICAgICBzdGF0ZVxuICAgIH07XG59XG4vKipcbiAqIEdpdmVuIGFuIGV4dGVuc2lvbiBJRCwgd2hpY2ggaXMgYSBzdHJpbmcgdW5pcXVlbHkgaWRlbnRpZnlpbmdcbiAqIGFuIGluc3RhbmNlIG9mIGFuIGV4dGVuc2lvbiB3aXRoaW4gYW4gZXh0ZW5zaW9uIHNsb3QsIHRoaXNcbiAqIHJldHVybnMgdGhlIGV4dGVuc2lvbiBuYW1lLlxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGBqc1xuICogZ2V0RXh0ZW5zaW9uTmFtZUZyb21JZChcImZvbyNiYXJcIilcbiAqICAtLT4gXCJmb29cIlxuICogZ2V0RXh0ZW5zaW9uTmFtZUZyb21JZChcImJhelwiKVxuICogIC0tPiBcImJhelwiXG4gKiBgYGBcbiAqLyBleHBvcnQgZnVuY3Rpb24gZ2V0RXh0ZW5zaW9uTmFtZUZyb21JZChleHRlbnNpb25JZCkge1xuICAgIGNvbnN0IFtleHRlbnNpb25OYW1lXSA9IGV4dGVuc2lvbklkLnNwbGl0KCcjJyk7XG4gICAgcmV0dXJuIGV4dGVuc2lvbk5hbWU7XG59XG5leHBvcnQgZnVuY3Rpb24gZ2V0RXh0ZW5zaW9uUmVnaXN0cmF0aW9uRnJvbShzdGF0ZSwgZXh0ZW5zaW9uSWQpIHtcbiAgICBjb25zdCBuYW1lID0gZ2V0RXh0ZW5zaW9uTmFtZUZyb21JZChleHRlbnNpb25JZCk7XG4gICAgcmV0dXJuIHN0YXRlLmV4dGVuc2lvbnNbbmFtZV07XG59XG5leHBvcnQgZnVuY3Rpb24gZ2V0RXh0ZW5zaW9uUmVnaXN0cmF0aW9uKGV4dGVuc2lvbklkKSB7XG4gICAgY29uc3Qgc3RhdGUgPSBleHRlbnNpb25JbnRlcm5hbFN0b3JlLmdldFN0YXRlKCk7XG4gICAgcmV0dXJuIGdldEV4dGVuc2lvblJlZ2lzdHJhdGlvbkZyb20oc3RhdGUsIGV4dGVuc2lvbklkKTtcbn1cbi8qKlxuICogRXh0ZW5zaW9ucyBtdXN0IGJlIHJlZ2lzdGVyZWQgaW4gb3JkZXIgdG8gYmUgcmVuZGVyZWQuXG4gKiBUaGlzIGlzIGhhbmRsZWQgYnkgdGhlIGFwcCBzaGVsbCwgd2hlbiBleHRlbnNpb25zIGFyZSBwcm92aWRlZFxuICogdmlhIHRoZSBgcm91dGVzLmpzb25gIGZpbGUgYW5kIHJlZ2lzdGVyZWQgdGhyb3VnaCBgcmVnaXN0ZXJBcHAoKWAuXG4gKiBAaW50ZXJuYWxcbiAqLyBleHBvcnQgY29uc3QgcmVnaXN0ZXJFeHRlbnNpb24gPSAoZXh0ZW5zaW9uUmVnaXN0cmF0aW9uKT0+ZXh0ZW5zaW9uSW50ZXJuYWxTdG9yZS5zZXRTdGF0ZSgoc3RhdGUpPT57XG4gICAgICAgIHN0YXRlLmV4dGVuc2lvbnNbZXh0ZW5zaW9uUmVnaXN0cmF0aW9uLm5hbWVdID0ge1xuICAgICAgICAgICAgLi4uZXh0ZW5zaW9uUmVnaXN0cmF0aW9uLFxuICAgICAgICAgICAgaW5zdGFuY2VzOiBbXVxuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gc3RhdGU7XG4gICAgfSk7XG4vKipcbiAqIEF0dGFjaCBhbiBleHRlbnNpb24gdG8gYW4gZXh0ZW5zaW9uIHNsb3QuXG4gKlxuICogVGhpcyB3aWxsIGNhdXNlIHRoZSBleHRlbnNpb24gdG8gYmUgcmVuZGVyZWQgaW50byB0aGUgc3BlY2lmaWVkXG4gKiBleHRlbnNpb24gc2xvdCwgdW5sZXNzIGl0IGlzIHJlbW92ZWQgYnkgY29uZmlndXJhdGlvbi4gVXNpbmdcbiAqIGBhdHRhY2hgIGlzIGFuIGFsdGVybmF0aXZlIHRvIHNwZWNpZnlpbmcgdGhlIGBzbG90YCBvciBgc2xvdHNgXG4gKiBpbiB0aGUgZXh0ZW5zaW9uIGRlY2xhcmF0aW9uLlxuICpcbiAqIEl0IGlzIHBhcnRpY3VsYXJseSB1c2VmdWwgd2hlbiBjcmVhdGluZyBhIHNsb3QgaW50byB3aGljaFxuICogeW91IHdhbnQgdG8gcmVuZGVyIGFuIGV4aXN0aW5nIGV4dGVuc2lvbi4gVGhpcyBlbmFibGVzIHlvdVxuICogdG8gZG8gc28gd2l0aG91dCBtb2RpZnlpbmcgdGhlIGV4dGVuc2lvbidzIGRlY2xhcmF0aW9uLCB3aGljaFxuICogbWF5IGJlIGltcHJhY3RpY2FsIG9yIGluYXBwcm9wcmlhdGUsIGZvciBleGFtcGxlIGlmIHlvdSBhcmVcbiAqIHdyaXRpbmcgYSBtb2R1bGUgZm9yIGEgc3BlY2lmaWMgaW1wbGVtZW50YXRpb24uXG4gKlxuICogQHBhcmFtIHNsb3ROYW1lIGEgbmFtZSB1bmlxdWVseSBpZGVudGlmeWluZyB0aGUgc2xvdFxuICogQHBhcmFtIGV4dGVuc2lvbklkIGFuIGV4dGVuc2lvbiBuYW1lLCB3aXRoIGFuIG9wdGlvbmFsICMtc3VmZml4XG4gKiAgICB0byBkaXN0aW5ndWlzaCBpdCBmcm9tIG90aGVyIGluc3RhbmNlcyBvZiB0aGUgc2FtZSBleHRlbnNpb25cbiAqICAgIGF0dGFjaGVkIHRvIHRoZSBzYW1lIHNsb3QuXG4gKi8gZXhwb3J0IGZ1bmN0aW9uIGF0dGFjaChzbG90TmFtZSwgZXh0ZW5zaW9uSWQpIHtcbiAgICB1cGRhdGVJbnRlcm5hbEV4dGVuc2lvblN0b3JlKChzdGF0ZSk9PntcbiAgICAgICAgY29uc3QgZXhpc3RpbmdTbG90ID0gc3RhdGUuc2xvdHNbc2xvdE5hbWVdO1xuICAgICAgICBpZiAoIWV4aXN0aW5nU2xvdCkge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAuLi5zdGF0ZSxcbiAgICAgICAgICAgICAgICBzbG90czoge1xuICAgICAgICAgICAgICAgICAgICAuLi5zdGF0ZS5zbG90cyxcbiAgICAgICAgICAgICAgICAgICAgW3Nsb3ROYW1lXToge1xuICAgICAgICAgICAgICAgICAgICAgICAgLi4uY3JlYXRlTmV3RXh0ZW5zaW9uU2xvdEluZm8oc2xvdE5hbWUpLFxuICAgICAgICAgICAgICAgICAgICAgICAgYXR0YWNoZWRJZHM6IFtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25JZFxuICAgICAgICAgICAgICAgICAgICAgICAgXVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgLi4uc3RhdGUsXG4gICAgICAgICAgICAgICAgc2xvdHM6IHtcbiAgICAgICAgICAgICAgICAgICAgLi4uc3RhdGUuc2xvdHMsXG4gICAgICAgICAgICAgICAgICAgIFtzbG90TmFtZV06IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC4uLmV4aXN0aW5nU2xvdCxcbiAgICAgICAgICAgICAgICAgICAgICAgIGF0dGFjaGVkSWRzOiBbXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLi4uZXhpc3RpbmdTbG90LmF0dGFjaGVkSWRzLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvbklkXG4gICAgICAgICAgICAgICAgICAgICAgICBdXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgfSk7XG59XG4vKipcbiAqIEBkZXByZWNhdGVkIEF2b2lkIHVzaW5nIHRoaXMuIEV4dGVuc2lvbiBhdHRhY2htZW50cyBzaG91bGQgYmUgY29uc2lkZXJlZCBkZWNsYXJhdGl2ZS5cbiAqLyBleHBvcnQgZnVuY3Rpb24gZGV0YWNoKGV4dGVuc2lvblNsb3ROYW1lLCBleHRlbnNpb25JZCkge1xuICAgIHVwZGF0ZUludGVybmFsRXh0ZW5zaW9uU3RvcmUoKHN0YXRlKT0+e1xuICAgICAgICBjb25zdCBleGlzdGluZ1Nsb3QgPSBzdGF0ZS5zbG90c1tleHRlbnNpb25TbG90TmFtZV07XG4gICAgICAgIGlmIChleGlzdGluZ1Nsb3QgJiYgZXhpc3RpbmdTbG90LmF0dGFjaGVkSWRzLmluY2x1ZGVzKGV4dGVuc2lvbklkKSkge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAuLi5zdGF0ZSxcbiAgICAgICAgICAgICAgICBzbG90czoge1xuICAgICAgICAgICAgICAgICAgICAuLi5zdGF0ZS5zbG90cyxcbiAgICAgICAgICAgICAgICAgICAgW2V4dGVuc2lvblNsb3ROYW1lXToge1xuICAgICAgICAgICAgICAgICAgICAgICAgLi4uZXhpc3RpbmdTbG90LFxuICAgICAgICAgICAgICAgICAgICAgICAgYXR0YWNoZWRJZHM6IGV4aXN0aW5nU2xvdC5hdHRhY2hlZElkcy5maWx0ZXIoKGlkKT0+aWQgIT09IGV4dGVuc2lvbklkKVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBzdGF0ZTtcbiAgICAgICAgfVxuICAgIH0pO1xufVxuLyoqXG4gKiBAZGVwcmVjYXRlZCBBdm9pZCB1c2luZyB0aGlzLiBFeHRlbnNpb24gYXR0YWNobWVudHMgc2hvdWxkIGJlIGNvbnNpZGVyZWQgZGVjbGFyYXRpdmUuXG4gKi8gZXhwb3J0IGZ1bmN0aW9uIGRldGFjaEFsbChleHRlbnNpb25TbG90TmFtZSkge1xuICAgIHVwZGF0ZUludGVybmFsRXh0ZW5zaW9uU3RvcmUoKHN0YXRlKT0+e1xuICAgICAgICBjb25zdCBleGlzdGluZ1Nsb3QgPSBzdGF0ZS5zbG90c1tleHRlbnNpb25TbG90TmFtZV07XG4gICAgICAgIGlmIChleGlzdGluZ1Nsb3QpIHtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgLi4uc3RhdGUsXG4gICAgICAgICAgICAgICAgc2xvdHM6IHtcbiAgICAgICAgICAgICAgICAgICAgLi4uc3RhdGUuc2xvdHMsXG4gICAgICAgICAgICAgICAgICAgIFtleHRlbnNpb25TbG90TmFtZV06IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC4uLmV4aXN0aW5nU2xvdCxcbiAgICAgICAgICAgICAgICAgICAgICAgIGF0dGFjaGVkSWRzOiBbXVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBzdGF0ZTtcbiAgICAgICAgfVxuICAgIH0pO1xufVxuLyoqXG4gKiBHZXQgYW4gb3JkZXIgaW5kZXggZm9yIHRoZSBleHRlbnNpb24uIFRoaXMgd2lsbFxuICogY29tZSBmcm9tIGVpdGhlciBpdHMgY29uZmlndXJlZCBvcmRlciwgaXRzIHJlZ2lzdGVyZWQgb3JkZXJcbiAqIHBhcmFtZXRlciwgb3IgdGhlIG9yZGVyIGluIHdoaWNoIGl0IGhhcHBlbmVkIHRvIGJlIGF0dGFjaGVkLlxuICovIGZ1bmN0aW9uIGdldE9yZGVyKGV4dGVuc2lvbklkLCBjb25maWd1cmVkT3JkZXIsIHJlZ2lzdGVyZWRPcmRlckluZGV4LCBhdHRhY2hlZE9yZGVyKSB7XG4gICAgY29uc3QgY29uZmlndXJlZEluZGV4ID0gY29uZmlndXJlZE9yZGVyLmluZGV4T2YoZXh0ZW5zaW9uSWQpO1xuICAgIGlmIChjb25maWd1cmVkSW5kZXggIT09IC0xKSB7XG4gICAgICAgIHJldHVybiBjb25maWd1cmVkSW5kZXg7XG4gICAgfSBlbHNlIGlmIChyZWdpc3RlcmVkT3JkZXJJbmRleCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIC8vIGV4dGVuc2lvbnMgdGhhdCBkb24ndCBoYXZlIGEgY29uZmlndXJlZCBvcmRlciBzaG91bGQgYXBwZWFyIGFmdGVyIHRob3NlIHRoYXQgZG9cbiAgICAgICAgcmV0dXJuIDEwMDAgKyByZWdpc3RlcmVkT3JkZXJJbmRleDtcbiAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCBhc3NpZ25lZEluZGV4ID0gYXR0YWNoZWRPcmRlci5pbmRleE9mKGV4dGVuc2lvbklkKTtcbiAgICAgICAgaWYgKGFzc2lnbmVkSW5kZXggIT09IC0xKSB7XG4gICAgICAgICAgICAvLyBleHRlbnNpb25zIHRoYXQgaGF2ZSBuZWl0aGVyIGEgY29uZmlndXJlZCBub3IgcmVnaXN0ZXJlZCBvcmRlciBzaG91bGQgYXBwZWFyXG4gICAgICAgICAgICAvLyBhZnRlciBhbGwgb3RoZXJzXG4gICAgICAgICAgICByZXR1cm4gMjAwMCArIGFzc2lnbmVkSW5kZXg7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gLTE7XG4gICAgICAgIH1cbiAgICB9XG59XG5mdW5jdGlvbiBnZXRBc3NpZ25lZEV4dGVuc2lvbnNGcm9tU2xvdERhdGEoc2xvdE5hbWUsIGludGVybmFsU3RhdGUsIGNvbmZpZywgZXh0ZW5zaW9uQ29uZmlnU3RvcmVTdGF0ZSwgZW5hYmxlZEZlYXR1cmVGbGFncywgaXNPbmxpbmUsIHNlc3Npb24pIHtcbiAgICBjb25zdCBhdHRhY2hlZElkcyA9IGludGVybmFsU3RhdGUuc2xvdHNbc2xvdE5hbWVdLmF0dGFjaGVkSWRzO1xuICAgIGNvbnN0IGFzc2lnbmVkSWRzID0gY2FsY3VsYXRlQXNzaWduZWRJZHMoY29uZmlnLCBhdHRhY2hlZElkcyk7XG4gICAgY29uc3QgZXh0ZW5zaW9ucyA9IFtdO1xuICAgIC8vIENyZWF0ZSBjb250ZXh0IG9uY2UgZm9yIGFsbCBleHRlbnNpb25zIGluIHRoaXMgc2xvdFxuICAgIGNvbnN0IHNsb3RTdGF0ZSA9IGludGVybmFsU3RhdGUuc2xvdHNbc2xvdE5hbWVdPy5zdGF0ZTtcbiAgICBjb25zdCBleHByZXNzaW9uQ29udGV4dCA9IHNsb3RTdGF0ZSAmJiB0eXBlb2Ygc2xvdFN0YXRlID09PSAnb2JqZWN0JyA/IHtcbiAgICAgICAgc2Vzc2lvbixcbiAgICAgICAgLi4uc2xvdFN0YXRlXG4gICAgfSA6IHtcbiAgICAgICAgc2Vzc2lvblxuICAgIH07XG4gICAgZm9yIChsZXQgaWQgb2YgYXNzaWduZWRJZHMpe1xuICAgICAgICBjb25zdCB7IGNvbmZpZzogcmF3RXh0ZW5zaW9uQ29uZmlnIH0gPSBnZXRFeHRlbnNpb25Db25maWdGcm9tU3RvcmUoZXh0ZW5zaW9uQ29uZmlnU3RvcmVTdGF0ZSwgc2xvdE5hbWUsIGlkKTtcbiAgICAgICAgY29uc3QgcmF3RXh0ZW5zaW9uU2xvdEV4dGVuc2lvbkNvbmZpZyA9IGdldEV4dGVuc2lvbkNvbmZpZ0Zyb21FeHRlbnNpb25TbG90U3RvcmUoY29uZmlnLCBzbG90TmFtZSwgaWQpO1xuICAgICAgICBjb25zdCBleHRlbnNpb25Db25maWcgPSBtZXJnZShyYXdFeHRlbnNpb25Db25maWcsIHJhd0V4dGVuc2lvblNsb3RFeHRlbnNpb25Db25maWcpO1xuICAgICAgICBjb25zdCBuYW1lID0gZ2V0RXh0ZW5zaW9uTmFtZUZyb21JZChpZCk7XG4gICAgICAgIGNvbnN0IGV4dGVuc2lvbiA9IGludGVybmFsU3RhdGUuZXh0ZW5zaW9uc1tuYW1lXTtcbiAgICAgICAgLy8gaWYgdGhlIGV4dGVuc2lvbiBoYXMgbm90IGJlZW4gcmVnaXN0ZXJlZCB5ZXQsIGRvIG5vdCBpbmNsdWRlIGl0XG4gICAgICAgIGlmIChleHRlbnNpb24pIHtcbiAgICAgICAgICAgIGNvbnN0IHJlcXVpcmVkUHJpdmlsZWdlcyA9IGV4dGVuc2lvbkNvbmZpZz8uWydEaXNwbGF5IGNvbmRpdGlvbnMnXT8ucHJpdmlsZWdlcyA/PyBleHRlbnNpb24ucHJpdmlsZWdlcyA/PyBbXTtcbiAgICAgICAgICAgIGlmIChyZXF1aXJlZFByaXZpbGVnZXMgJiYgKHR5cGVvZiByZXF1aXJlZFByaXZpbGVnZXMgPT09ICdzdHJpbmcnIHx8IEFycmF5LmlzQXJyYXkocmVxdWlyZWRQcml2aWxlZ2VzKSAmJiByZXF1aXJlZFByaXZpbGVnZXMubGVuZ3RoID4gMCkpIHtcbiAgICAgICAgICAgICAgICBpZiAoIXNlc3Npb24/LnVzZXIpIHtcbiAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICghdXNlckhhc0FjY2VzcyhyZXF1aXJlZFByaXZpbGVnZXMsIHNlc3Npb24udXNlcikpIHtcbiAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgZGlzcGxheUNvbmRpdGlvbkV4cHJlc3Npb24gPSBleHRlbnNpb25Db25maWc/LlsnRGlzcGxheSBjb25kaXRpb25zJ10/LmV4cHJlc3Npb24gfHwgZXh0ZW5zaW9uLmRpc3BsYXlFeHByZXNzaW9uO1xuICAgICAgICAgICAgaWYgKGRpc3BsYXlDb25kaXRpb25FeHByZXNzaW9uICE9PSB1bmRlZmluZWQgJiYgdHlwZW9mIGRpc3BsYXlDb25kaXRpb25FeHByZXNzaW9uID09PSAnc3RyaW5nJyAmJiBkaXNwbGF5Q29uZGl0aW9uRXhwcmVzc2lvbi50cmltKCkubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICghZXZhbHVhdGVBc0Jvb2xlYW4oZGlzcGxheUNvbmRpdGlvbkV4cHJlc3Npb24sIGV4cHJlc3Npb25Db250ZXh0KSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYEVycm9yIHdoaWxlIGV2YWx1YXRpbmcgZXhwcmVzc2lvbiAnJHtkaXNwbGF5Q29uZGl0aW9uRXhwcmVzc2lvbn0nIGZvciBleHRlbnNpb24gJHtuYW1lfSBpbiBzbG90ICR7c2xvdE5hbWV9YCwgZSk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChleHRlbnNpb24uZmVhdHVyZUZsYWcgJiYgIWVuYWJsZWRGZWF0dXJlRmxhZ3MuaW5jbHVkZXMoZXh0ZW5zaW9uLmZlYXR1cmVGbGFnKSkge1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHdpbmRvdy5vZmZsaW5lRW5hYmxlZCAmJiAhY2hlY2tTdGF0dXNGb3IoaXNPbmxpbmUsIGV4dGVuc2lvbi5vbmxpbmUsIGV4dGVuc2lvbi5vZmZsaW5lKSkge1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZXh0ZW5zaW9ucy5wdXNoKHtcbiAgICAgICAgICAgICAgICBpZCxcbiAgICAgICAgICAgICAgICBuYW1lLFxuICAgICAgICAgICAgICAgIG1vZHVsZU5hbWU6IGV4dGVuc2lvbi5tb2R1bGVOYW1lLFxuICAgICAgICAgICAgICAgIGNvbmZpZzogZXh0ZW5zaW9uQ29uZmlnLFxuICAgICAgICAgICAgICAgIGZlYXR1cmVGbGFnOiBleHRlbnNpb24uZmVhdHVyZUZsYWcsXG4gICAgICAgICAgICAgICAgbWV0YTogZXh0ZW5zaW9uLm1ldGEsXG4gICAgICAgICAgICAgICAgb25saW5lOiBleHRlbnNpb25Db25maWc/LlsnRGlzcGxheSBjb25kaXRpb25zJ10/Lm9ubGluZSA/PyBleHRlbnNpb24ub25saW5lID8/IHRydWUsXG4gICAgICAgICAgICAgICAgb2ZmbGluZTogZXh0ZW5zaW9uQ29uZmlnPy5bJ0Rpc3BsYXkgY29uZGl0aW9ucyddPy5vZmZsaW5lID8/IGV4dGVuc2lvbi5vZmZsaW5lID8/IGZhbHNlXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZXh0ZW5zaW9ucztcbn1cbi8qKlxuICogR2V0cyB0aGUgbGlzdCBvZiBleHRlbnNpb25zIGFzc2lnbmVkIHRvIGEgZ2l2ZW4gc2xvdFxuICpcbiAqIEBwYXJhbSBzbG90TmFtZSBUaGUgc2xvdCB0byBsb2FkIHRoZSBhc3NpZ25lZCBleHRlbnNpb25zIGZvclxuICogQHJldHVybnMgQW4gYXJyYXkgb2YgZXh0ZW5zaW9ucyBhc3NpZ25lZCB0byB0aGUgbmFtZWQgc2xvdFxuICovIGV4cG9ydCBmdW5jdGlvbiBnZXRBc3NpZ25lZEV4dGVuc2lvbnMoc2xvdE5hbWUpIHtcbiAgICBjb25zdCBpbnRlcm5hbFN0YXRlID0gZXh0ZW5zaW9uSW50ZXJuYWxTdG9yZS5nZXRTdGF0ZSgpO1xuICAgIGNvbnN0IHsgY29uZmlnOiBzbG90Q29uZmlnIH0gPSBnZXRFeHRlbnNpb25TbG90Q29uZmlnKHNsb3ROYW1lKTtcbiAgICBjb25zdCBleHRlbnNpb25TdG9yZVN0YXRlID0gZXh0ZW5zaW9uc0NvbmZpZ1N0b3JlLmdldFN0YXRlKCk7XG4gICAgY29uc3QgZmVhdHVyZUZsYWdTdGF0ZSA9IGZlYXR1cmVGbGFnc1N0b3JlLmdldFN0YXRlKCk7XG4gICAgY29uc3Qgc2Vzc2lvblN0YXRlID0gc2Vzc2lvblN0b3JlLmdldFN0YXRlKCk7XG4gICAgY29uc3QgaXNPbmxpbmUgPSBpc09ubGluZUZuKCk7XG4gICAgY29uc3QgZW5hYmxlZEZlYXR1cmVGbGFncyA9IE9iamVjdC5lbnRyaWVzKGZlYXR1cmVGbGFnU3RhdGUuZmxhZ3MpLmZpbHRlcigoWywgeyBlbmFibGVkIH1dKT0+ZW5hYmxlZCkubWFwKChbbmFtZV0pPT5uYW1lKTtcbiAgICByZXR1cm4gZ2V0QXNzaWduZWRFeHRlbnNpb25zRnJvbVNsb3REYXRhKHNsb3ROYW1lLCBpbnRlcm5hbFN0YXRlLCBzbG90Q29uZmlnLCBleHRlbnNpb25TdG9yZVN0YXRlLCBlbmFibGVkRmVhdHVyZUZsYWdzLCBpc09ubGluZSwgc2Vzc2lvblN0YXRlLnNlc3Npb24pO1xufVxuZnVuY3Rpb24gY2FsY3VsYXRlQXNzaWduZWRJZHMoY29uZmlnLCBhdHRhY2hlZElkcykge1xuICAgIGNvbnN0IGFkZGVkSWRzID0gY29uZmlnLmFkZCB8fCBbXTtcbiAgICBjb25zdCByZW1vdmVkSWRzID0gY29uZmlnLnJlbW92ZSB8fCBbXTtcbiAgICBjb25zdCBpZE9yZGVyID0gY29uZmlnLm9yZGVyIHx8IFtdO1xuICAgIGNvbnN0IHsgZXh0ZW5zaW9ucyB9ID0gZXh0ZW5zaW9uSW50ZXJuYWxTdG9yZS5nZXRTdGF0ZSgpO1xuICAgIHJldHVybiBbXG4gICAgICAgIC4uLmF0dGFjaGVkSWRzLFxuICAgICAgICAuLi5hZGRlZElkc1xuICAgIF0uZmlsdGVyKChpZCk9PiFyZW1vdmVkSWRzLmluY2x1ZGVzKGlkKSkuc29ydCgoaWRBLCBpZEIpPT57XG4gICAgICAgIGNvbnN0IGFpID0gZ2V0T3JkZXIoaWRBLCBpZE9yZGVyLCBleHRlbnNpb25zW2dldEV4dGVuc2lvbk5hbWVGcm9tSWQoaWRBKV0/Lm9yZGVyLCBhdHRhY2hlZElkcyk7XG4gICAgICAgIGNvbnN0IGJpID0gZ2V0T3JkZXIoaWRCLCBpZE9yZGVyLCBleHRlbnNpb25zW2dldEV4dGVuc2lvbk5hbWVGcm9tSWQoaWRCKV0/Lm9yZGVyLCBhdHRhY2hlZElkcyk7XG4gICAgICAgIGlmIChiaSA9PT0gLTEpIHtcbiAgICAgICAgICAgIHJldHVybiAtMTtcbiAgICAgICAgfSBlbHNlIGlmIChhaSA9PT0gLTEpIHtcbiAgICAgICAgICAgIHJldHVybiAxO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIGFpIC0gYmk7XG4gICAgICAgIH1cbiAgICB9KTtcbn1cbi8qKlxuICogVXNlZCBieSBieSBleHRlbnNpb24gc2xvdHMgYXQgbW91bnQgdGltZS5cbiAqXG4gKiBAcGFyYW0gbW9kdWxlTmFtZSBUaGUgbmFtZSBvZiB0aGUgbW9kdWxlIHRoYXQgY29udGFpbnMgdGhlIGV4dGVuc2lvbiBzbG90XG4gKiBAcGFyYW0gc2xvdE5hbWUgVGhlIGV4dGVuc2lvbiBzbG90IG5hbWUgdGhhdCBpcyBhY3R1YWxseSB1c2VkXG4gKiBAcGFyYW0gc3RhdGUgT3B0aW9uYWwgY3VzdG9tIHN0YXRlIGZvciB0aGUgc2xvdCwgd2hpY2ggd2lsbCBiZSBzdG9yZWQgaW4gdGhlIGV4dGVuc2lvbiBzdG9yZS5cbiAqIEBpbnRlcm5hbFxuICovIGV4cG9ydCBjb25zdCByZWdpc3RlckV4dGVuc2lvblNsb3QgPSAobW9kdWxlTmFtZSwgc2xvdE5hbWUsIHN0YXRlKT0+ZXh0ZW5zaW9uSW50ZXJuYWxTdG9yZS5zZXRTdGF0ZSgoY3VycmVudFN0YXRlKT0+e1xuICAgICAgICBjb25zdCBleGlzdGluZ01vZHVsZU5hbWUgPSBjdXJyZW50U3RhdGUuc2xvdHNbc2xvdE5hbWVdPy5tb2R1bGVOYW1lO1xuICAgICAgICBpZiAoZXhpc3RpbmdNb2R1bGVOYW1lICYmIGV4aXN0aW5nTW9kdWxlTmFtZSAhPSBtb2R1bGVOYW1lKSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oYEFuIGV4dGVuc2lvbiBzbG90IHdpdGggdGhlIG5hbWUgJyR7c2xvdE5hbWV9JyBhbHJlYWR5IGV4aXN0cy4gUmVmdXNpbmcgdG8gcmVnaXN0ZXIgdGhlIHNhbWUgc2xvdCBuYW1lIHR3aWNlIChpbiBcInJlZ2lzdGVyRXh0ZW5zaW9uU2xvdFwiKS4gVGhlIGV4aXN0aW5nIG9uZSBpcyBmcm9tIG1vZHVsZSAke2V4aXN0aW5nTW9kdWxlTmFtZX0uYCk7XG4gICAgICAgICAgICByZXR1cm4gY3VycmVudFN0YXRlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChleGlzdGluZ01vZHVsZU5hbWUgJiYgZXhpc3RpbmdNb2R1bGVOYW1lID09IG1vZHVsZU5hbWUpIHtcbiAgICAgICAgICAgIC8vIFJlLXJlbmRlcmluZyBhbiBleGlzdGluZyBzbG90XG4gICAgICAgICAgICByZXR1cm4gY3VycmVudFN0YXRlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChjdXJyZW50U3RhdGUuc2xvdHNbc2xvdE5hbWVdKSB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIC4uLmN1cnJlbnRTdGF0ZSxcbiAgICAgICAgICAgICAgICBzbG90czoge1xuICAgICAgICAgICAgICAgICAgICAuLi5jdXJyZW50U3RhdGUuc2xvdHMsXG4gICAgICAgICAgICAgICAgICAgIFtzbG90TmFtZV06IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC4uLmN1cnJlbnRTdGF0ZS5zbG90c1tzbG90TmFtZV0sXG4gICAgICAgICAgICAgICAgICAgICAgICBtb2R1bGVOYW1lLFxuICAgICAgICAgICAgICAgICAgICAgICAgc3RhdGVcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgc2xvdCA9IGNyZWF0ZU5ld0V4dGVuc2lvblNsb3RJbmZvKHNsb3ROYW1lLCBtb2R1bGVOYW1lLCBzdGF0ZSk7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAuLi5jdXJyZW50U3RhdGUsXG4gICAgICAgICAgICBzbG90czoge1xuICAgICAgICAgICAgICAgIC4uLmN1cnJlbnRTdGF0ZS5zbG90cyxcbiAgICAgICAgICAgICAgICBbc2xvdE5hbWVdOiB7XG4gICAgICAgICAgICAgICAgICAgIC4uLnNsb3RcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfSk7XG4vKipcbiAqIFVzZWQgYnkgZXh0ZW5zaW9uIHNsb3RzIHRvIHVwZGF0ZSB0aGUgY29weSBvZiB0aGUgc3RhdGUgZm9yIHRoZSBleHRlbnNpb24gc2xvdFxuICpcbiAqIEBwYXJhbSBzbG90TmFtZSBUaGUgbmFtZSBvZiB0aGUgc2xvdCB3aXRoIHN0YXRlIHRvIHVwZGF0ZVxuICogQHBhcmFtIHN0YXRlIEEgY29weSBvZiB0aGUgbmV3IHN0YXRlXG4gKiBAcGFyYW0gcGFydGlhbCBXaGV0aGVyIHRoaXMgc2hvdWxkIGJlIGFwcGxpZWQgYXMgYSBwYXJ0aWFsXG4gKi8gZXhwb3J0IGZ1bmN0aW9uIHVwZGF0ZUV4dGVuc2lvblNsb3RTdGF0ZShzbG90TmFtZSwgc3RhdGUsIHBhcnRpYWwgPSBmYWxzZSkge1xuICAgIGV4dGVuc2lvbkludGVybmFsU3RvcmUuc2V0U3RhdGUoKGN1cnJlbnRTdGF0ZSk9PntcbiAgICAgICAgY29uc3QgbmV3U3RhdGUgPSBwYXJ0aWFsID8gbWVyZ2UoY3VycmVudFN0YXRlLnNsb3RzW3Nsb3ROYW1lXS5zdGF0ZSwgc3RhdGUpIDogc3RhdGU7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAuLi5jdXJyZW50U3RhdGUsXG4gICAgICAgICAgICBzbG90czoge1xuICAgICAgICAgICAgICAgIC4uLmN1cnJlbnRTdGF0ZS5zbG90cyxcbiAgICAgICAgICAgICAgICBbc2xvdE5hbWVdOiB7XG4gICAgICAgICAgICAgICAgICAgIC4uLmN1cnJlbnRTdGF0ZS5zbG90c1tzbG90TmFtZV0sXG4gICAgICAgICAgICAgICAgICAgIHN0YXRlOiBuZXdTdGF0ZVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9KTtcbn1cbi8qKlxuICogQGludGVybmFsXG4gKiBKdXN0IGZvciB0ZXN0aW5nLlxuICovIGV4cG9ydCBjb25zdCByZXNldCA9ICgpPT5leHRlbnNpb25TdG9yZS5zZXRTdGF0ZSgoKT0+e1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgc2xvdHM6IHt9LFxuICAgICAgICAgICAgZXh0ZW5zaW9uczoge31cbiAgICAgICAgfTtcbiAgICB9KTtcbiJdLCJuYW1lcyI6WyJzZXNzaW9uU3RvcmUiLCJ1c2VySGFzQWNjZXNzIiwiZ2V0RXh0ZW5zaW9uQ29uZmlnRnJvbUV4dGVuc2lvblNsb3RTdG9yZSIsImdldEV4dGVuc2lvbkNvbmZpZ0Zyb21TdG9yZSIsImdldEV4dGVuc2lvblNsb3RDb25maWciLCJnZXRFeHRlbnNpb25TbG90Q29uZmlnRnJvbVN0b3JlIiwiZ2V0RXh0ZW5zaW9uU2xvdHNDb25maWdTdG9yZSIsImdldEV4dGVuc2lvbnNDb25maWdTdG9yZSIsImV2YWx1YXRlQXNCb29sZWFuIiwiZmVhdHVyZUZsYWdzU3RvcmUiLCJzdWJzY3JpYmVDb25uZWN0aXZpdHlDaGFuZ2VkIiwiaXNPbmxpbmUiLCJpc09ubGluZUZuIiwiaXNFcXVhbCIsIm1lcmdlIiwiY2hlY2tTdGF0dXNGb3IiLCJnZXRFeHRlbnNpb25JbnRlcm5hbFN0b3JlIiwiZ2V0RXh0ZW5zaW9uU3RvcmUiLCJ1cGRhdGVJbnRlcm5hbEV4dGVuc2lvblN0b3JlIiwiZXh0ZW5zaW9uSW50ZXJuYWxTdG9yZSIsImV4dGVuc2lvblN0b3JlIiwic2xvdHNDb25maWdTdG9yZSIsImV4dGVuc2lvbnNDb25maWdTdG9yZSIsInVwZGF0ZUV4dGVuc2lvbk91dHB1dFN0b3JlIiwiaW50ZXJuYWxTdGF0ZSIsImV4dGVuc2lvblNsb3RDb25maWdzIiwiZmVhdHVyZUZsYWdTdG9yZSIsInNsb3RzIiwiZW5hYmxlZEZlYXR1cmVGbGFncyIsIk9iamVjdCIsImVudHJpZXMiLCJmbGFncyIsImZpbHRlciIsImVuYWJsZWQiLCJtYXAiLCJuYW1lIiwic2xvdE5hbWUiLCJzbG90IiwiY29uZmlnIiwiYXNzaWduZWRFeHRlbnNpb25zIiwiZ2V0QXNzaWduZWRFeHRlbnNpb25zRnJvbVNsb3REYXRhIiwic2Vzc2lvbiIsIm1vZHVsZU5hbWUiLCJnZXRTdGF0ZSIsInNldFN0YXRlIiwic3Vic2NyaWJlIiwiaW50ZXJuYWxTdG9yZSIsInNsb3RDb25maWdzIiwiZXh0ZW5zaW9uQ29uZmlncyIsInVwZGF0ZU91dHB1dFN0b3JlVG9DdXJyZW50IiwiY3JlYXRlTmV3RXh0ZW5zaW9uU2xvdEluZm8iLCJzdGF0ZSIsImF0dGFjaGVkSWRzIiwiZ2V0RXh0ZW5zaW9uTmFtZUZyb21JZCIsImV4dGVuc2lvbklkIiwiZXh0ZW5zaW9uTmFtZSIsInNwbGl0IiwiZ2V0RXh0ZW5zaW9uUmVnaXN0cmF0aW9uRnJvbSIsImV4dGVuc2lvbnMiLCJnZXRFeHRlbnNpb25SZWdpc3RyYXRpb24iLCJyZWdpc3RlckV4dGVuc2lvbiIsImV4dGVuc2lvblJlZ2lzdHJhdGlvbiIsImluc3RhbmNlcyIsImF0dGFjaCIsImV4aXN0aW5nU2xvdCIsImRldGFjaCIsImV4dGVuc2lvblNsb3ROYW1lIiwiaW5jbHVkZXMiLCJpZCIsImRldGFjaEFsbCIsImdldE9yZGVyIiwiY29uZmlndXJlZE9yZGVyIiwicmVnaXN0ZXJlZE9yZGVySW5kZXgiLCJhdHRhY2hlZE9yZGVyIiwiY29uZmlndXJlZEluZGV4IiwiaW5kZXhPZiIsInVuZGVmaW5lZCIsImFzc2lnbmVkSW5kZXgiLCJleHRlbnNpb25Db25maWdTdG9yZVN0YXRlIiwiYXNzaWduZWRJZHMiLCJjYWxjdWxhdGVBc3NpZ25lZElkcyIsInNsb3RTdGF0ZSIsImV4cHJlc3Npb25Db250ZXh0IiwicmF3RXh0ZW5zaW9uQ29uZmlnIiwicmF3RXh0ZW5zaW9uU2xvdEV4dGVuc2lvbkNvbmZpZyIsImV4dGVuc2lvbkNvbmZpZyIsImV4dGVuc2lvbiIsInJlcXVpcmVkUHJpdmlsZWdlcyIsInByaXZpbGVnZXMiLCJBcnJheSIsImlzQXJyYXkiLCJsZW5ndGgiLCJ1c2VyIiwiZGlzcGxheUNvbmRpdGlvbkV4cHJlc3Npb24iLCJleHByZXNzaW9uIiwiZGlzcGxheUV4cHJlc3Npb24iLCJ0cmltIiwiZSIsImNvbnNvbGUiLCJlcnJvciIsImZlYXR1cmVGbGFnIiwid2luZG93Iiwib2ZmbGluZUVuYWJsZWQiLCJvbmxpbmUiLCJvZmZsaW5lIiwicHVzaCIsIm1ldGEiLCJnZXRBc3NpZ25lZEV4dGVuc2lvbnMiLCJzbG90Q29uZmlnIiwiZXh0ZW5zaW9uU3RvcmVTdGF0ZSIsImZlYXR1cmVGbGFnU3RhdGUiLCJzZXNzaW9uU3RhdGUiLCJhZGRlZElkcyIsImFkZCIsInJlbW92ZWRJZHMiLCJyZW1vdmUiLCJpZE9yZGVyIiwib3JkZXIiLCJzb3J0IiwiaWRBIiwiaWRCIiwiYWkiLCJiaSIsInJlZ2lzdGVyRXh0ZW5zaW9uU2xvdCIsImN1cnJlbnRTdGF0ZSIsImV4aXN0aW5nTW9kdWxlTmFtZSIsIndhcm4iLCJ1cGRhdGVFeHRlbnNpb25TbG90U3RhdGUiLCJwYXJ0aWFsIiwibmV3U3RhdGUiLCJyZXNldCJdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///../../framework/esm-extensions/dist/extensions.js\n");
449
449
 
450
450
  /***/ }),
451
451